Skip to content
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

[BACKUP] TypeScript support using Babel 7, with monorepo support #1

Closed
wants to merge 9 commits into from
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ The [User Guide](https://github.com/facebook/create-react-app/blob/master/packag
- [Using Global Variables](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#using-global-variables)
- [Adding Bootstrap](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-bootstrap)
- [Adding Flow](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-flow)
- [Adding TypeScript](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-typescript)
- [Adding a Router](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-router)
- [Adding Custom Environment Variables](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables)
- [Can I Use Decorators?](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#can-i-use-decorators)
Expand Down Expand Up @@ -216,7 +217,7 @@ Here’s a few common cases where you might want to try something else:

* If your website is **mostly static** (for example, a portfolio or a blog), consider using [Gatsby](https://www.gatsbyjs.org/) instead. Unlike Create React App, it pre-renders the website into HTML at the build time.

* If you want to use **TypeScript**, consider using [create-react-app-typescript](https://github.com/wmonk/create-react-app-typescript).
* If you want an alternative way to use **TypeScript**, consider using [create-react-app-typescript](https://github.com/wmonk/create-react-app-typescript).

* If you want to use **Parcel** instead of **Webpack** as your bundler, consider using [create-react-app-parcel](https://github.com/sw-yx/create-react-app-parcel).

Expand Down
2 changes: 1 addition & 1 deletion packages/babel-plugin-named-asset-import/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
"index.js"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.46"
"@babel/core": "7.1.0"
}
}
24 changes: 15 additions & 9 deletions packages/babel-preset-react-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,25 @@ Then create a file named `.babelrc` with following contents in the root folder o

This preset uses the `useBuiltIns` option with [transform-object-rest-spread](http://babeljs.io/docs/plugins/transform-object-rest-spread/) and [transform-react-jsx](http://babeljs.io/docs/plugins/transform-react-jsx/), which assumes that `Object.assign` is available or polyfilled.

## Usage with TypeScript
## Usage with Flow

To use this package with [`@babel/preset-flow`]https://www.npmjs.com/package/@babel/preset-flow), you only need to have a `.flowconfig` file at the root directory and it will be detected automatically. Alternatively, you can edit `.babelrc` with the following:

```
{
"presets": [["react-app", { "flow": true }]]
}
```

To use this package with [`@babel/preset-typescript`](https://www.npmjs.com/package/@babel/preset-typescript), you need to disable `@babel/preset-flow` first.

You can achieve this by doing:
## Usage with TypeScript

To use this package with [`@babel/preset-typescript`]https://www.npmjs.com/package/@babel/preset-typescript), you only need to have a `tsconfig.json` file at the root directory and it will be detected automatically. Alternatively, you can edit `.babelrc` with the following:

```
{
"presets": [
["react-app", {
"flow": false
}],
"@babel/typescript"
]
"presets": [["react-app", { "typescript": true }]]
}
```

TSLint is also automatically supported, you only need to create a `tslint.json` (and optionally a `tslint.prod.json`) file at the root directory.
26 changes: 24 additions & 2 deletions packages/babel-preset-react-app/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
*/
'use strict';

const path = require('path');
const fs = require('fs');

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);

const hasFlowConfig = fs.existsSync(resolveApp('.flowconfig'));
const hasTSConfig = fs.existsSync(resolveApp('tsconfig.json'));

const validateBoolOption = (name, value, defaultValue) => {
if (typeof value === 'undefined') {
value = defaultValue;
Expand All @@ -26,7 +35,12 @@ module.exports = function(api, opts, env) {
var isEnvDevelopment = env === 'development';
var isEnvProduction = env === 'production';
var isEnvTest = env === 'test';
var isFlowEnabled = validateBoolOption('flow', opts.flow, true);
var isFlowEnabled = validateBoolOption('flow', opts.flow, hasFlowConfig);
var isTypeScriptEnabled = validateBoolOption(
'typescript',
opts.typescript,
hasTSConfig
);

if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) {
throw new Error(
Expand All @@ -38,6 +52,14 @@ module.exports = function(api, opts, env) {
);
}

if (isFlowEnabled && isTypeScriptEnabled) {
throw new Error(
'Cannot enable both flow and typescript support in the same project. ' +
"Please make sure you don't have both .flowconfig and tsconfig.json files. '" +
'If using .babelrc, set one option to false and the other one to true.'
);
}

return {
presets: [
isEnvTest && [
Expand Down Expand Up @@ -75,6 +97,7 @@ module.exports = function(api, opts, env) {
},
],
isFlowEnabled && [require('@babel/preset-flow').default],
isTypeScriptEnabled && [require('@babel/preset-typescript').default],
].filter(Boolean),
plugins: [
// Experimental macros support. Will be documented after it's had some time
Expand Down Expand Up @@ -107,7 +130,6 @@ module.exports = function(api, opts, env) {
require('@babel/plugin-transform-runtime').default,
{
helpers: false,
polyfill: false,
regenerator: true,
},
],
Expand Down
31 changes: 16 additions & 15 deletions packages/babel-preset-react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,22 @@
"test.js"
],
"dependencies": {
"@babel/core": "7.0.0-beta.46",
"@babel/plugin-proposal-class-properties": "7.0.0-beta.46",
"@babel/plugin-proposal-object-rest-spread": "7.0.0-beta.46",
"@babel/plugin-syntax-dynamic-import": "7.0.0-beta.46",
"@babel/plugin-transform-classes": "7.0.0-beta.46",
"@babel/plugin-transform-destructuring": "7.0.0-beta.46",
"@babel/plugin-transform-react-constant-elements": "7.0.0-beta.46",
"@babel/plugin-transform-react-display-name": "7.0.0-beta.46",
"@babel/plugin-transform-regenerator": "7.0.0-beta.46",
"@babel/plugin-transform-runtime": "7.0.0-beta.46",
"@babel/preset-env": "7.0.0-beta.46",
"@babel/preset-flow": "7.0.0-beta.46",
"@babel/preset-react": "7.0.0-beta.46",
"babel-plugin-macros": "2.2.1",
"@babel/core": "7.1.0",
"@babel/plugin-proposal-class-properties": "7.1.0",
"@babel/plugin-proposal-object-rest-spread": "7.0.0",
"@babel/plugin-syntax-dynamic-import": "7.0.0",
"@babel/plugin-transform-classes": "7.1.0",
"@babel/plugin-transform-destructuring": "7.0.0",
"@babel/plugin-transform-react-constant-elements": "7.0.0",
"@babel/plugin-transform-react-display-name": "7.0.0",
"@babel/plugin-transform-regenerator": "7.0.0",
"@babel/plugin-transform-runtime": "7.1.0",
"@babel/preset-env": "7.1.0",
"@babel/preset-flow": "7.0.0",
"@babel/preset-react": "7.0.0",
"@babel/preset-typescript": "7.1.0",
"babel-plugin-macros": "2.4.1",
"babel-plugin-transform-dynamic-import": "2.0.0",
"babel-plugin-transform-react-remove-prop-types": "0.4.13"
"babel-plugin-transform-react-remove-prop-types": "0.4.15"
}
}
5 changes: 4 additions & 1 deletion packages/react-dev-utils/WebpackDevServerUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ function createCompiler(webpack, config, appName, urls, useYarn) {
console.log(chalk.yellow('Compiled with warnings.\n'));
console.log(messages.warnings.join('\n\n'));

// Teach some ESLint tricks.
// Teach some ESLint / TSLint tricks.
console.log(
'\nSearch for the ' +
chalk.underline(chalk.yellow('keywords')) +
Expand All @@ -186,6 +186,9 @@ function createCompiler(webpack, config, appName, urls, useYarn) {
console.log(
'To ignore, add ' +
chalk.cyan('// eslint-disable-next-line') +
' (or ' +
chalk.cyan('// tslint:disable-next-line') +
' if TypeScript)' +
' to the line before.\n'
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/react-dev-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"workspaceUtils.js"
],
"dependencies": {
"@babel/code-frame": "7.0.0-beta.46",
"@babel/code-frame": "7.0.0",
"address": "1.0.3",
"browserslist": "3.2.6",
"chalk": "2.4.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-error-overlay/.babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"presets": ["react-app"]
"presets": [["react-app", { "flow": true }]]
}
12 changes: 6 additions & 6 deletions packages/react-error-overlay/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
"lib/index.js"
],
"devDependencies": {
"@babel/code-frame": "7.0.0-beta.46",
"@babel/core": "7.0.0-beta.46",
"@babel/runtime": "7.0.0-beta.46",
"@babel/code-frame": "7.0.0",
"@babel/core": "7.1.0",
"@babel/runtime": "7.0.0",
"anser": "1.4.6",
"babel-core": "^7.0.0-bridge.0",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "^8.2.2",
"babel-jest": "^22.4.3",
"babel-loader": "^8.0.0-beta.0",
"babel-jest": "23.6.0",
"babel-loader": "8.0.2",
"babel-preset-react-app": "^3.1.1",
"chalk": "^2.3.2",
"chokidar": "^2.0.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/react-error-overlay/webpack.config.iframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ module.exports = {
oneOf: [
// Source
{
test: /\.js$/,
test: /\.(js)|(tsx?)$/,
include: [path.resolve(__dirname, './src')],
use: {
loader: 'babel-loader',
},
},
// Dependencies
{
test: /\.js$/,
test: /\.(js)|(tsx?)$/,
use: {
loader: 'babel-loader',
options: {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-error-overlay/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module.exports = {
use: 'raw-loader',
},
{
test: /\.js$/,
test: /\.(js)|(tsx?)$/,
include: path.resolve(__dirname, './src'),
use: 'babel-loader',
},
Expand Down
50 changes: 44 additions & 6 deletions packages/react-scripts/config/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,34 @@ function getServedPath(appPackageJson) {
return ensureSlash(servedUrl, true);
}

const hasTSConfig = fs.existsSync(resolveApp('tsconfig.json'));
const hasTSConfigProd = fs.existsSync(resolveApp('tsconfig.prod.json'));

const hasTSLint = fs.existsSync(resolveApp('tslint.json'));
const hasTSLintProd = fs.existsSync(resolveApp('tslint.prod.json'));

const isTypeScript = hasTSConfig;

// config after eject: we're in ./config/
module.exports = {
dotenv: resolveApp('.env'),
appPath: resolveApp('.'),
appBuild: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveApp('src/index.js'),
appIndexJs: isTypeScript
? resolveApp('src/index.tsx')
: resolveApp('src/index.js'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
testsSetup: resolveApp('src/setupTests.js'),
testsSetup: isTypeScript
? resolveApp('src/setupTests.ts')
: resolveApp('src/setupTests.js'),
appNodeModules: resolveApp('node_modules'),
appTSConfig: resolveApp('tsconfig.json'),
appTSConfigProd: resolveApp('tsconfig.prod.json'),
appTSLint: resolveApp('tslint.json'),
appTSLintProd: resolveApp('tslint.prod.json'),
publicUrl: getPublicUrl(resolveApp('package.json')),
servedPath: getServedPath(resolveApp('package.json')),
};
Expand All @@ -75,11 +91,19 @@ module.exports = {
appBuild: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveApp('src/index.js'),
appIndexJs: isTypeScript
? resolveApp('src/index.tsx')
: resolveApp('src/index.js'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
testsSetup: resolveApp('src/setupTests.js'),
testsSetup: isTypeScript
? resolveApp('src/setupTests.ts')
: resolveApp('src/setupTests.js'),
appNodeModules: resolveApp('node_modules'),
appTSConfig: resolveApp('tsconfig.json'),
appTSConfigProd: resolveApp('tsconfig.prod.json'),
appTSLint: resolveApp('tslint.json'),
appTSLintProd: resolveApp('tslint.prod.json'),
publicUrl: getPublicUrl(resolveApp('package.json')),
servedPath: getServedPath(resolveApp('package.json')),
// These properties only exist before ejecting:
Expand All @@ -100,11 +124,19 @@ if (useTemplate) {
appBuild: resolveOwn('../../build'),
appPublic: resolveOwn('template/public'),
appHtml: resolveOwn('template/public/index.html'),
appIndexJs: resolveOwn('template/src/index.js'),
appIndexJs: isTypeScript
? resolveOwn('template/src/index.tsx')
: resolveOwn('template/src/index.js'),
appPackageJson: resolveOwn('package.json'),
appSrc: resolveOwn('template/src'),
testsSetup: resolveOwn('template/src/setupTests.js'),
testsSetup: isTypeScript
? resolveOwn('template/src/setupTests.ts')
: resolveOwn('template/src/setupTests.js'),
appNodeModules: resolveOwn('node_modules'),
appTSConfig: resolveOwn('template/tsconfig.json'),
appTSConfigProd: resolveOwn('template/tsconfig.prod.json'),
appTSLint: resolveOwn('template/tslint.json'),
appTSLintProd: resolveOwn('template/tslint.prod.json'),
publicUrl: getPublicUrl(resolveOwn('package.json')),
servedPath: getServedPath(resolveOwn('package.json')),
// These properties only exist before ejecting:
Expand All @@ -116,6 +148,12 @@ if (useTemplate) {

module.exports.srcPaths = [module.exports.appSrc];

module.exports.isTypeScript = isTypeScript;
module.exports.useTSConfigProd = isTypeScript && hasTSConfigProd;

module.exports.useTSLint = isTypeScript && hasTSLint;
module.exports.useTSLintProd = isTypeScript && hasTSLintProd;

module.exports.useYarn = fs.existsSync(
path.join(module.exports.appPath, 'yarn.lock')
);
Expand Down
Loading