diff --git a/packages/babel-preset-react-app/index.js b/packages/babel-preset-react-app/index.js index 1f7ec0f8e0eedda8fc7de47002a0af26df7d7284..05dd8eb9650b1b559a2b6d26e9fd98d45d256cde 100644 --- a/packages/babel-preset-react-app/index.js +++ b/packages/babel-preset-react-app/index.js @@ -14,7 +14,7 @@ const plugins = [ // class { handleClick = () => { } } require.resolve('babel-plugin-transform-class-properties'), // The following two plugins use Object.assign directly, instead of Babel's - // extends helper. Note that this assumes `Object.assign` is available. + // extends helper. Note that this assumes `Object.assign` is available. // { ...todo, completed: true } [require.resolve('babel-plugin-transform-object-rest-spread'), { useBuiltIns: true @@ -69,39 +69,60 @@ if (env === 'development' || env === 'test') { } if (env === 'test') { - module.exports = { - presets: [ - // ES features necessary for user's Node version - [require('babel-preset-env').default, { - targets: { - node: 'current', - }, - }], - // JSX, Flow - require.resolve('babel-preset-react') - ], - plugins: plugins + module.exports = function() { + return { + presets: [ + // ES features necessary for user's Node version + [require('babel-preset-env').default, { + targets: { + node: 'current', + }, + }], + // JSX, Flow + require.resolve('babel-preset-react') + ], + plugins: plugins + }; + }; +} else if (env ==='production') { + // Optimization: hoist JSX that never changes out of render() + // Disabled because of issues: + // * https://github.com/facebookincubator/create-react-app/issues/525 + // * https://phabricator.babeljs.io/search/query/pCNlnC2xzwzx/ + // * https://github.com/babel/babel/issues/4516 + // TODO: Enable again when these issues are resolved. + // plugins.push.apply(plugins, [ + // require.resolve('babel-plugin-transform-react-constant-elements') + // ]); + + module.exports = function(context, opts) { + // A simple transform to cherry-pick Lodash modules so you don’t have to. + if (opts && opts.isUsingLodash === true) { + plugins.push.apply(plugins, [ + require.resolve('babel-plugin-lodash') + ]); + } + + return { + presets: [ + // Latest stable ECMAScript features + require.resolve('babel-preset-latest'), + // JSX, Flow + require.resolve('babel-preset-react') + ], + plugins: plugins + }; }; } else { - module.exports = { - presets: [ - // Latest stable ECMAScript features - require.resolve('babel-preset-latest'), - // JSX, Flow - require.resolve('babel-preset-react') - ], - plugins: plugins + module.exports = function() { + return { + presets: [ + // Latest stable ECMAScript features + require.resolve('babel-preset-latest'), + // JSX, Flow + require.resolve('babel-preset-react') + ], + plugins: plugins + }; }; - - if (env === 'production') { - // Optimization: hoist JSX that never changes out of render() - // Disabled because of issues: - // * https://github.com/facebookincubator/create-react-app/issues/525 - // * https://phabricator.babeljs.io/search/query/pCNlnC2xzwzx/ - // * https://github.com/babel/babel/issues/4516 - // TODO: Enable again when these issues are resolved. - // plugins.push.apply(plugins, [ - // require.resolve('babel-plugin-transform-react-constant-elements') - // ]); - } } diff --git a/packages/babel-preset-react-app/package.json b/packages/babel-preset-react-app/package.json index 08a210674ee4107956cd9d220a5cfa151a45d6cb..9e77b5471b7fbccff97ff68a771430b79581d49f 100644 --- a/packages/babel-preset-react-app/package.json +++ b/packages/babel-preset-react-app/package.json @@ -11,6 +11,7 @@ "index.js" ], "dependencies": { + "babel-plugin-lodash": "3.2.10", "babel-plugin-transform-class-properties": "6.16.0", "babel-plugin-transform-object-rest-spread": "6.19.0", "babel-plugin-transform-react-constant-elements": "6.9.1", diff --git a/packages/react-scripts/.babelrc b/packages/react-scripts/.babelrc index ad8e03a8248d2fcadd20ad2f5e19c8e2a339af27..041c2fedbdee0985451f4087b85e999bdeacde93 100644 --- a/packages/react-scripts/.babelrc +++ b/packages/react-scripts/.babelrc @@ -1,3 +1,5 @@ { - "presets": ["react-app"] -} \ No newline at end of file + "presets": [ + ["react-app", { "isUsingLodash": false } ] + ] +} diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 60016896892cdd40efb02634bd77607a557bb099..01e4fb8eefb074e1ee73ee43e3b89132abd4fd30 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -19,6 +19,7 @@ var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); var url = require('url'); var paths = require('./paths'); var getClientEnvironment = require('./env'); +var appPackageJson = require(paths.appPackageJson) function ensureSlash(path, needsSlash) { var hasSlash = path.endsWith('/'); @@ -31,12 +32,16 @@ function ensureSlash(path, needsSlash) { } } +// If `lodash` is present into app package.json we apply `babel-plugin-lodash` +// through the `isUsingLodash` option of `babel-preset-react-app` to reduce build size +var isUsingLodash = !!appPackageJson.dependencies.lodash + // We use "homepage" field to infer "public path" at which the app is served. // Webpack needs to know it to put the right <script> hrefs into HTML even in // single-page apps that may serve index.html for nested URLs like /todos/42. // We can't use a relative path in HTML because we don't want to load something // like /todos/42/static/js/bundle.7289d.js. We have to know the root. -var homepagePath = require(paths.appPackageJson).homepage; +var homepagePath = appPackageJson.homepage; var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/'; // Webpack uses `publicPath` to determine where the app is being served from. // It requires a trailing slash, or the file assets will get an incorrect path. @@ -149,7 +154,7 @@ module.exports = { // @remove-on-eject-begin query: { babelrc: false, - presets: [require.resolve('babel-preset-react-app')], + presets: [[require.resolve('babel-preset-react-app'), {isUsingLodash: isUsingLodash}]], }, // @remove-on-eject-end },