Skip to content

Discussion: TypeScript support #509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ build
*.tgz
my-app*
template/src/__tests__/__snapshots__/
.awcache
20 changes: 19 additions & 1 deletion config/jest/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,23 @@

const babelDev = require('../babel.dev');
const babelJest = require('babel-jest');
const tsc = require('typescript');
const babelTransformer = babelJest.createTransformer(babelDev);

module.exports = babelJest.createTransformer(babelDev);
// transpile the source with TypeScript, if needed, and then with Babel
module.exports = {
process(src, path) {
if (path.endsWith('.ts') || path.endsWith('.tsx')) {
src = tsc.transpile(
src,
{
module: tsc.ModuleKind.CommonJS,
jsx: tsc.JsxEmit.React,
},
path,
[]
);
}
return babelTransformer.process(src, path);
},
};
26 changes: 26 additions & 0 deletions config/typescript.dev.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

var path = require('path');
var paths = require('./paths');

// strip cacheDirectory since it's a babel-loader specific option
var babelOptions = Object.assign({}, require('./babel.dev'))
delete babelOptions['cacheDirectory']

module.exports = {
// uses the cache to improve dev performance
useCache: true,
// when TypeScript emits a file, pass it to Babel to provide backwards compatibility
useBabel: true,
// these are the options to use
babelOptions: babelOptions,
// tell the loader where the path is
babelCore: path.join(paths.appNodeModules, 'babel-core')
};
20 changes: 20 additions & 0 deletions config/typescript.prod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

var path = require('path');
var paths = require('./paths');

module.exports = {
// when TypeScript emits a file, pass it to Babel to provide backwards compatibility
useBabel: true,
// these are the options to use
babelOptions: require('./babel.prod'),
// tell the loader where the path is
babelCore: path.join(paths.appNodeModules, 'babel-core')
};
17 changes: 15 additions & 2 deletions config/webpack.config.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ module.exports = {
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
extensions: ['.js', '.json', '.jsx', ''],
// We support also TypeScript ts and tsx which will be compiled later
extensions: ['.ts', '.tsx', '.js', '.json', '.jsx', ''],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
Expand All @@ -93,15 +94,27 @@ module.exports = {
},
module: {
// First, run the linter.
// It's important to do this before Babel processes the JS.
// It's important to do this before Babel or TypeScript processes the JS/TS.
preLoaders: [
{
test: /\.(js|jsx)$/,
loader: 'eslint',
include: paths.appSrc,
},
{
test: /\.tsx?$/,
loader: 'tslint',
include: paths.appSrc
}
],
loaders: [
// Process TS with TypeScript and then with Babel
{
test: /\.tsx?$/,
include: paths.appSrc,
loader: 'awesome-typescript',
query: require('./typescript.dev')
},
// Process JS with Babel.
{
test: /\.(js|jsx)$/,
Expand Down
17 changes: 15 additions & 2 deletions config/webpack.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ module.exports = {
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
extensions: ['.js', '.json', '.jsx', ''],
// We support also TypeScript ts and tsx which will be compiled later
extensions: ['.ts', '.tsx', '.js', '.json', '.jsx', ''],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
Expand All @@ -88,15 +89,27 @@ module.exports = {
},
module: {
// First, run the linter.
// It's important to do this before Babel processes the JS.
// It's important to do this before Babel or TypeScript processes the JS/TS.
preLoaders: [
{
test: /\.(js|jsx)$/,
loader: 'eslint',
include: paths.appSrc
},
{
test: /\.tsx?$/,
loader: 'tslint',
include: paths.appSrc
}
],
loaders: [
// Process TS with TypeScript and then with Babel
{
test: /\.tsx?$/,
include: paths.appSrc,
loader: 'awesome-typescript',
query: require('./typescript.prod')
},
// Process JS with Babel.
{
test: /\.(js|jsx)$/,
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"dependencies": {
"autoprefixer": "6.4.0",
"awesome-typescript-loader": "^2.2.1",
"babel-core": "6.14.0",
"babel-eslint": "6.1.2",
"babel-jest": "15.0.0",
Expand Down Expand Up @@ -72,6 +73,9 @@
"rimraf": "2.5.4",
"strip-ansi": "3.0.1",
"style-loader": "0.13.1",
"tslint": "^3.15.1",
"tslint-loader": "^2.1.5",
"typescript": "^2.0.0",
"url-loader": "0.5.7",
"webpack": "1.13.2",
"webpack-dev-server": "1.15.1",
Expand Down
2 changes: 2 additions & 0 deletions scripts/eject.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ prompt(
path.join('config', 'paths.js'),
path.join('config', 'env.js'),
path.join('config', 'polyfills.js'),
path.join('config', 'typescript.dev.js'),
path.join('config', 'typescript.prod.js'),
path.join('config', 'webpack.config.dev.js'),
path.join('config', 'webpack.config.prod.js'),
path.join('config', 'jest', 'CSSStub.js'),
Expand Down
4 changes: 3 additions & 1 deletion scripts/utils/createJestConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ module.exports = (resolve, rootDir) => {
}

const config = {
moduleFileExtensions: ['jsx', 'js', 'json'],
// allow Jest to load TypeScript modules
moduleFileExtensions: ['jsx', 'js', 'json', 'ts', 'tsx'],
automock: false,
moduleNameMapper: {
'^[./a-zA-Z0-9$_-]+\\.(jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm)$': resolve('config/jest/FileStub.js'),
'^[./a-zA-Z0-9$_-]+\\.css$': resolve('config/jest/CSSStub.js')
Expand Down
2 changes: 2 additions & 0 deletions template/src/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Component } from 'react';
import {HelloTypeScript} from './HelloTypeScript'
import logo from './logo.svg';
import './App.css';

Expand All @@ -13,6 +14,7 @@ class App extends Component {
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<HelloTypeScript />
</div>
);
}
Expand Down
8 changes: 8 additions & 0 deletions template/src/HelloTypeScript.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as React from "react";
const {Component} = React;

export class HelloTypeScript extends Component<any, any> {
render() {
return <p>If you'd like to, you can also use TypeScript!</p>;
}
}
12 changes: 12 additions & 0 deletions template/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "es2015",
"jsx": "react"
},
"include": [
"src"
],
"files": [
"./typings/index.d.ts"
]
}
7 changes: 7 additions & 0 deletions template/typings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "create-react-app",
"dependencies": {
"react": "registry:npm/react#15.0.1+20160601175240",
"react-dom": "registry:npm/react-dom#15.0.1+20160826174104"
}
}
2 changes: 2 additions & 0 deletions template/typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference path="modules/react-dom/index.d.ts" />
/// <reference path="modules/react/index.d.ts" />
Loading