Skip to content
3 changes: 2 additions & 1 deletion packages/babel-preset-react-app/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module.exports = function(api, opts, env) {
var isEnvProduction = env === 'production';
var isEnvTest = env === 'test';
var isFlowEnabled = validateBoolOption('flow', opts.flow, true);
var areHelpersEnabled = validateBoolOption('helpers', opts.helpers, false);

if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) {
throw new Error(
Expand Down Expand Up @@ -113,7 +114,7 @@ module.exports = function(api, opts, env) {
require('@babel/plugin-transform-runtime').default,
{
corejs: false,
helpers: false,
helpers: areHelpersEnabled,
regenerator: true,
// https://babeljs.io/docs/en/babel-plugin-transform-runtime#useesmodules
// We should turn this on once the lowest version of Node LTS
Expand Down
15 changes: 14 additions & 1 deletion packages/babel-preset-react-app/dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@
*/
'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) {
if (!opts) {
opts = {};
Expand All @@ -21,6 +33,7 @@ module.exports = function(api, opts) {
var isEnvDevelopment = env === 'development';
var isEnvProduction = env === 'production';
var isEnvTest = env === 'test';
var areHelpersEnabled = validateBoolOption('helpers', opts.helpers, false);
if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) {
throw new Error(
'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' +
Expand Down Expand Up @@ -76,7 +89,7 @@ module.exports = function(api, opts) {
require('@babel/plugin-transform-runtime').default,
{
corejs: false,
helpers: false,
helpers: areHelpersEnabled,
regenerator: true,
// https://babeljs.io/docs/en/babel-plugin-transform-runtime#useesmodules
// We should turn this on once the lowest version of Node LTS
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", { "helpers": true }]]
}
5 changes: 4 additions & 1 deletion packages/react-error-overlay/webpack.config.iframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ module.exports = {
// Dependencies
{
test: /\.js$/,
exclude: /@babel\/runtime/,
use: {
loader: 'babel-loader',
options: {
babelrc: false,
compact: false,
presets: ['babel-preset-react-app/dependencies'],
presets: [
['babel-preset-react-app/dependencies', { helpers: true }],
],
},
},
},
Expand Down
13 changes: 11 additions & 2 deletions packages/react-scripts/config/webpack.config.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,12 @@ module.exports = {
options: {
// @remove-on-eject-begin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is removed on eject. Where do we decide what to write on eject? Seems like we'd lose this. Maybe it means I wasn't right about the app default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

babelrc: false,
presets: [require.resolve('babel-preset-react-app')],
presets: [
[
require.resolve('babel-preset-react-app'),
{ helpers: true },
],
],
// Make sure we have a unique cache identifier, erring on the
// side of caution.
// We remove this when the user ejects because the default
Expand Down Expand Up @@ -275,6 +280,7 @@ module.exports = {
// Unlike the application JS, we only compile the standard ES features.
{
test: /\.js$/,
exclude: /@babel\/runtime/,
use: [
// This loader parallelizes code compilation, it is optional but
// improves compile time on larger projects
Expand All @@ -290,7 +296,10 @@ module.exports = {
babelrc: false,
compact: false,
presets: [
require.resolve('babel-preset-react-app/dependencies'),
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
cacheDirectory: true,
// Don't waste time on Gzipping the cache
Expand Down
13 changes: 11 additions & 2 deletions packages/react-scripts/config/webpack.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,12 @@ module.exports = {
options: {
// @remove-on-eject-begin
babelrc: false,
presets: [require.resolve('babel-preset-react-app')],
presets: [
[
require.resolve('babel-preset-react-app'),
{ helpers: true },
],
],
// Make sure we have a unique cache identifier, erring on the
// side of caution.
// We remove this when the user ejects because the default
Expand Down Expand Up @@ -314,6 +319,7 @@ module.exports = {
// Unlike the application JS, we only compile the standard ES features.
{
test: /\.js$/,
exclude: /@babel\/runtime/,
use: [
// This loader parallelizes code compilation, it is optional but
// improves compile time on larger projects
Expand All @@ -324,7 +330,10 @@ module.exports = {
babelrc: false,
compact: false,
presets: [
require.resolve('babel-preset-react-app/dependencies'),
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
cacheDirectory: true,
// Save disk space when time isn't as important
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"dependencies": {
"bootstrap": "4.1.1",
"jest": "23.6.0",
"ky": "0.3.0",
"node-sass": "4.8.3",
"normalize.css": "7.0.0",
"prop-types": "15.5.6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ describe('Integration', () => {
doc.defaultView.close();
});

it('babel node modules', async () => {
const doc = await initDOM('babel-node-modules');

expect(
doc.getElementById('feature-babel-node-modules').childElementCount
).toBe(1);
doc.defaultView.close();
});

it('object destructuring', async () => {
const doc = await initDOM('object-destructuring');

Expand Down
5 changes: 5 additions & 0 deletions packages/react-scripts/fixtures/kitchensink/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ class App extends Component {
this.setFeature(f.default)
);
break;
case 'babel-node-modules':
import('./features/syntax/NodeModulesCompilation').then(f =>
this.setFeature(f.default)
);
break;
case 'image-inclusion':
import('./features/webpack/ImageInclusion').then(f =>
this.setFeature(f.default)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* 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.
*/

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ky from 'ky';

export default class extends Component {
static propTypes = {
onReady: PropTypes.func.isRequired,
};

state = { ip: null };

async componentDidMount() {
const ip = await ky.get('https://canihazip.com/s').text();
this.setState({ ip });
}

componentDidUpdate() {
this.props.onReady();
}

render() {
return (
<div id="feature-babel-node-modules">
{this.state.ip ? <span>{this.state.ip}</span> : null}
</div>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* 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.
*/

import React from 'react';
import ReactDOM from 'react-dom';

describe('node_modules compile', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
return import('./NodeModulesCompilation').then(
({ default: NodeModulesCompilation }) => {
return new Promise(resolve => {
ReactDOM.render(<NodeModulesCompilation onReady={resolve} />, div);
});
}
);
});
});
2 changes: 1 addition & 1 deletion packages/react-scripts/scripts/eject.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ inquirer
// Add Babel config
console.log(` Adding ${cyan('Babel')} preset`);
appPackage.babel = {
presets: ['react-app'],
presets: [['react-app', { helpers: true }]],
};

// Add ESlint config
Expand Down
4 changes: 0 additions & 4 deletions tasks/e2e-kitchensink.sh
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,6 @@ PORT=3001 \
nohup yarn start &>$tmp_server_log &
grep -q 'You can now view' <(tail -f $tmp_server_log)

# Before running Mocha, specify that it should use our preset
# TODO: this is very hacky and we should find some other solution
echo '{"presets":["react-app"]}' > .babelrc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad find, this broke the tests.


# Test "development" environment
E2E_URL="http://localhost:3001" \
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
Expand Down