1 | /**
|
2 | * Copyright (c) 2015-present, Facebook, Inc.
|
3 | *
|
4 | * This source code is licensed under the MIT license found in the
|
5 | * LICENSE file in the root directory of this source tree.
|
6 | */
|
7 | ;
|
8 |
|
9 | const path = require('path');
|
10 |
|
11 | const validateBoolOption = (name, value, defaultValue) => {
|
12 | if (typeof value === 'undefined') {
|
13 | value = defaultValue;
|
14 | }
|
15 |
|
16 | if (typeof value !== 'boolean') {
|
17 | throw new Error(`Preset react-app: '${name}' option must be a boolean.`);
|
18 | }
|
19 |
|
20 | return value;
|
21 | };
|
22 |
|
23 | module.exports = function(api, opts) {
|
24 | if (!opts) {
|
25 | opts = {};
|
26 | }
|
27 |
|
28 | // This is similar to how `env` works in Babel:
|
29 | // https://babeljs.io/docs/usage/babelrc/#env-option
|
30 | // We are not using `env` because it’s ignored in versions > babel-core@6.10.4:
|
31 | // https://github.com/babel/babel/issues/4539
|
32 | // https://github.com/facebook/create-react-app/issues/720
|
33 | // It’s also nice that we can enforce `NODE_ENV` being specified.
|
34 | var env = process.env.BABEL_ENV || process.env.NODE_ENV;
|
35 | var isEnvDevelopment = env === 'development';
|
36 | var isEnvProduction = env === 'production';
|
37 | var isEnvTest = env === 'test';
|
38 |
|
39 | var areHelpersEnabled = validateBoolOption('helpers', opts.helpers, false);
|
40 | var useAbsoluteRuntime = validateBoolOption(
|
41 | 'absoluteRuntime',
|
42 | opts.absoluteRuntime,
|
43 | true
|
44 | );
|
45 |
|
46 | var absoluteRuntimePath = undefined;
|
47 | if (useAbsoluteRuntime) {
|
48 | absoluteRuntimePath = path.dirname(
|
49 | require.resolve('@babel/runtime/package.json')
|
50 | );
|
51 | }
|
52 |
|
53 | if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) {
|
54 | throw new Error(
|
55 | 'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' +
|
56 | '`BABEL_ENV` environment variables. Valid values are "development", ' +
|
57 | '"test", and "production". Instead, received: ' +
|
58 | JSON.stringify(env) +
|
59 | '.'
|
60 | );
|
61 | }
|
62 |
|
63 | return {
|
64 | // Babel assumes ES Modules, which isn't safe until CommonJS
|
65 | // dies. This changes the behavior to assume CommonJS unless
|
66 | // an `import` or `export` is present in the file.
|
67 | // https://github.com/webpack/webpack/issues/4039#issuecomment-419284940
|
68 | sourceType: 'unambiguous',
|
69 | presets: [
|
70 | isEnvTest && [
|
71 | // ES features necessary for user's Node version
|
72 | require('@babel/preset-env').default,
|
73 | {
|
74 | targets: {
|
75 | node: 'current',
|
76 | },
|
77 | // Do not transform modules to CJS
|
78 | modules: false,
|
79 | // Exclude transforms that make all code slower
|
80 | exclude: ['transform-typeof-symbol'],
|
81 | },
|
82 | ],
|
83 | (isEnvProduction || isEnvDevelopment) && [
|
84 | // Latest stable ECMAScript features
|
85 | require('@babel/preset-env').default,
|
86 | {
|
87 | // Allow importing core-js in entrypoint and use browserlist to select polyfills
|
88 | useBuiltIns: 'entry',
|
89 | // Set the corejs version we are using to avoid warnings in console
|
90 | // This will need to change once we upgrade to corejs@3
|
91 | corejs: 3,
|
92 | // Do not transform modules to CJS
|
93 | modules: false,
|
94 | // Exclude transforms that make all code slower
|
95 | exclude: ['transform-typeof-symbol'],
|
96 | },
|
97 | ],
|
98 | ].filter(Boolean),
|
99 | plugins: [
|
100 | // Necessary to include regardless of the environment because
|
101 | // in practice some other transforms (such as object-rest-spread)
|
102 | // don't work without it: https://github.com/babel/babel/issues/7215
|
103 | [
|
104 | require('@babel/plugin-transform-destructuring').default,
|
105 | {
|
106 | // Use loose mode for performance:
|
107 | // https://github.com/facebook/create-react-app/issues/5602
|
108 | loose: false,
|
109 | selectiveLoose: [
|
110 | 'useState',
|
111 | 'useEffect',
|
112 | 'useContext',
|
113 | 'useReducer',
|
114 | 'useCallback',
|
115 | 'useMemo',
|
116 | 'useRef',
|
117 | 'useImperativeHandle',
|
118 | 'useLayoutEffect',
|
119 | 'useDebugValue',
|
120 | ],
|
121 | },
|
122 | ],
|
123 | // Polyfills the runtime needed for async/await, generators, and friends
|
124 | // https://babeljs.io/docs/en/babel-plugin-transform-runtime
|
125 | [
|
126 | require('@babel/plugin-transform-runtime').default,
|
127 | {
|
128 | corejs: false,
|
129 | helpers: areHelpersEnabled,
|
130 | regenerator: true,
|
131 | // https://babeljs.io/docs/en/babel-plugin-transform-runtime#useesmodules
|
132 | // We should turn this on once the lowest version of Node LTS
|
133 | // supports ES Modules.
|
134 | useESModules: isEnvDevelopment || isEnvProduction,
|
135 | // Undocumented option that lets us encapsulate our runtime, ensuring
|
136 | // the correct version is used
|
137 | // https://github.com/babel/babel/blob/090c364a90fe73d36a30707fc612ce037bdbbb24/packages/babel-plugin-transform-runtime/src/index.js#L35-L42
|
138 | absoluteRuntime: absoluteRuntimePath,
|
139 | },
|
140 | ],
|
141 | // Adds syntax support for import()
|
142 | require('@babel/plugin-syntax-dynamic-import').default,
|
143 | isEnvTest &&
|
144 | // Transform dynamic import to require
|
145 | require('babel-plugin-transform-dynamic-import').default,
|
146 | ].filter(Boolean),
|
147 | };
|
148 | };
|