diff --git a/packages/babel-preset-react-app/create.js b/packages/babel-preset-react-app/create.js new file mode 100644 index 00000000000..2ead09570f6 --- /dev/null +++ b/packages/babel-preset-react-app/create.js @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +const validateBoolOption = (name, value, defaultValue) => { + if (typeof value === 'undefined') { + value = defaultValue; + } + + if (typeof value !== 'boolean') { + throw new Error(`Preset react-app: '${name}' option must be a boolean.`); + } + + return value; +}; + +module.exports = function(api, opts, env) { + if (!opts) { + opts = {}; + } + + var isEnvDevelopment = env === 'development'; + var isEnvProduction = env === 'production'; + var isEnvTest = env === 'test'; + var isFlowEnabled = validateBoolOption('flow', opts.flow, true); + + if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) { + throw new Error( + 'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' + + '`BABEL_ENV` environment variables. Valid values are "development", ' + + '"test", and "production". Instead, received: ' + + JSON.stringify(env) + + '.' + ); + } + + return { + presets: [ + isEnvTest && [ + // ES features necessary for user's Node version + require('@babel/preset-env').default, + { + targets: { + node: '6.12', + }, + }, + ], + (isEnvProduction || isEnvDevelopment) && [ + // Latest stable ECMAScript features + require('@babel/preset-env').default, + { + // `entry` transforms `@babel/polyfill` into individual requires for + // the targeted browsers. This is safer than `usage` which performs + // static code analysis to determine what's required. + // This is probably a fine default to help trim down bundles when + // end-users inevitably import '@babel/polyfill'. + useBuiltIns: 'entry', + // Do not transform modules to CJS + modules: false, + }, + ], + [ + require('@babel/preset-react').default, + { + // Adds component stack to warning messages + // Adds __self attribute to JSX which React will use for some warnings + development: isEnvDevelopment || isEnvTest, + // Will use the native built-in instead of trying to polyfill + // behavior for any plugins that require one. + useBuiltIns: true, + }, + ], + isFlowEnabled && [require('@babel/preset-flow').default], + ].filter(Boolean), + plugins: [ + // Experimental macros support. Will be documented after it's had some time + // in the wild. + require('babel-plugin-macros'), + // Necessary to include regardless of the environment because + // in practice some other transforms (such as object-rest-spread) + // don't work without it: https://github.com/babel/babel/issues/7215 + require('@babel/plugin-transform-destructuring').default, + // class { handleClick = () => { } } + // Enable loose mode to use assignment instead of defineProperty + // See discussion in https://github.com/facebook/create-react-app/issues/4263 + [ + require('@babel/plugin-proposal-class-properties').default, + { + loose: true, + }, + ], + // The following two plugins use Object.assign directly, instead of Babel's + // extends helper. Note that this assumes `Object.assign` is available. + // { ...todo, completed: true } + [ + require('@babel/plugin-proposal-object-rest-spread').default, + { + useBuiltIns: true, + }, + ], + // Polyfills the runtime needed for async/await and generators + [ + require('@babel/plugin-transform-runtime').default, + { + helpers: false, + polyfill: false, + regenerator: true, + }, + ], + isEnvProduction && [ + // Remove PropTypes from production build + require('babel-plugin-transform-react-remove-prop-types').default, + { + removeImport: true, + }, + ], + // function* () { yield 42; yield 43; } + !isEnvTest && [ + require('@babel/plugin-transform-regenerator').default, + { + // Async functions are converted to generators by @babel/preset-env + async: false, + }, + ], + // Adds syntax support for import() + require('@babel/plugin-syntax-dynamic-import').default, + isEnvTest && + // Transform dynamic import to require + require('babel-plugin-transform-dynamic-import').default, + ].filter(Boolean), + }; +}; diff --git a/packages/babel-preset-react-app/dev.js b/packages/babel-preset-react-app/dev.js new file mode 100644 index 00000000000..8eb986bd59c --- /dev/null +++ b/packages/babel-preset-react-app/dev.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +const create = require('./create'); + +module.exports = function(api, opts) { + return create(api, opts, 'development'); +}; diff --git a/packages/babel-preset-react-app/index.js b/packages/babel-preset-react-app/index.js index 72089b9b78b..621af951619 100644 --- a/packages/babel-preset-react-app/index.js +++ b/packages/babel-preset-react-app/index.js @@ -6,138 +6,15 @@ */ 'use strict'; -const validateBoolOption = (name, value, defaultValue) => { - if (typeof value === 'undefined') { - value = defaultValue; - } - - if (typeof value !== 'boolean') { - throw new Error(`Preset react-app: '${name}' option must be a boolean.`); - } - - return value; -}; +const create = require('./create'); module.exports = function(api, opts) { - if (!opts) { - opts = {}; - } - // This is similar to how `env` works in Babel: // https://babeljs.io/docs/usage/babelrc/#env-option // We are not using `env` because it’s ignored in versions > babel-core@6.10.4: // https://github.com/babel/babel/issues/4539 // https://github.com/facebook/create-react-app/issues/720 // It’s also nice that we can enforce `NODE_ENV` being specified. - var env = process.env.BABEL_ENV || process.env.NODE_ENV; - var isEnvDevelopment = env === 'development'; - var isEnvProduction = env === 'production'; - var isEnvTest = env === 'test'; - var isFlowEnabled = validateBoolOption('flow', opts.flow, true); - - if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) { - throw new Error( - 'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' + - '`BABEL_ENV` environment variables. Valid values are "development", ' + - '"test", and "production". Instead, received: ' + - JSON.stringify(env) + - '.' - ); - } - - return { - presets: [ - isEnvTest && [ - // ES features necessary for user's Node version - require('@babel/preset-env').default, - { - targets: { - node: '6.12', - }, - }, - ], - (isEnvProduction || isEnvDevelopment) && [ - // Latest stable ECMAScript features - require('@babel/preset-env').default, - { - // `entry` transforms `@babel/polyfill` into individual requires for - // the targeted browsers. This is safer than `usage` which performs - // static code analysis to determine what's required. - // This is probably a fine default to help trim down bundles when - // end-users inevitably import '@babel/polyfill'. - useBuiltIns: 'entry', - // Do not transform modules to CJS - modules: false, - }, - ], - [ - require('@babel/preset-react').default, - { - // Adds component stack to warning messages - // Adds __self attribute to JSX which React will use for some warnings - development: isEnvDevelopment || isEnvTest, - // Will use the native built-in instead of trying to polyfill - // behavior for any plugins that require one. - useBuiltIns: true, - }, - ], - isFlowEnabled && [require('@babel/preset-flow').default], - ].filter(Boolean), - plugins: [ - // Experimental macros support. Will be documented after it's had some time - // in the wild. - require('babel-plugin-macros'), - // Necessary to include regardless of the environment because - // in practice some other transforms (such as object-rest-spread) - // don't work without it: https://github.com/babel/babel/issues/7215 - require('@babel/plugin-transform-destructuring').default, - // class { handleClick = () => { } } - // Enable loose mode to use assignment instead of defineProperty - // See discussion in https://github.com/facebook/create-react-app/issues/4263 - [ - require('@babel/plugin-proposal-class-properties').default, - { - loose: true, - }, - ], - // The following two plugins use Object.assign directly, instead of Babel's - // extends helper. Note that this assumes `Object.assign` is available. - // { ...todo, completed: true } - [ - require('@babel/plugin-proposal-object-rest-spread').default, - { - useBuiltIns: true, - }, - ], - // Polyfills the runtime needed for async/await and generators - [ - require('@babel/plugin-transform-runtime').default, - { - helpers: false, - polyfill: false, - regenerator: true, - }, - ], - isEnvProduction && [ - // Remove PropTypes from production build - require('babel-plugin-transform-react-remove-prop-types').default, - { - removeImport: true, - }, - ], - // function* () { yield 42; yield 43; } - !isEnvTest && [ - require('@babel/plugin-transform-regenerator').default, - { - // Async functions are converted to generators by @babel/preset-env - async: false, - }, - ], - // Adds syntax support for import() - require('@babel/plugin-syntax-dynamic-import').default, - isEnvTest && - // Transform dynamic import to require - require('babel-plugin-transform-dynamic-import').default, - ].filter(Boolean), - }; + const env = process.env.BABEL_ENV || process.env.NODE_ENV; + return create(api, opts, env); }; diff --git a/packages/babel-preset-react-app/package.json b/packages/babel-preset-react-app/package.json index 32054a98747..27b70195299 100644 --- a/packages/babel-preset-react-app/package.json +++ b/packages/babel-preset-react-app/package.json @@ -9,7 +9,11 @@ }, "files": [ "index.js", - "dependencies.js" + "create.js", + "dependencies.js", + "dev.js", + "prod.js", + "test.js" ], "dependencies": { "@babel/core": "7.0.0-beta.46", diff --git a/packages/babel-preset-react-app/prod.js b/packages/babel-preset-react-app/prod.js new file mode 100644 index 00000000000..9e3697f3eea --- /dev/null +++ b/packages/babel-preset-react-app/prod.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +const create = require('./create'); + +module.exports = function(api, opts) { + return create(api, opts, 'production'); +}; diff --git a/packages/babel-preset-react-app/test.js b/packages/babel-preset-react-app/test.js new file mode 100644 index 00000000000..15558ff2c4b --- /dev/null +++ b/packages/babel-preset-react-app/test.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +const create = require('./create'); + +module.exports = function(api, opts) { + return create(api, opts, 'test'); +};