create.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. 'use strict';
  8. const path = require('path');
  9. const validateBoolOption = (name, value, defaultValue) => {
  10. if (typeof value === 'undefined') {
  11. value = defaultValue;
  12. }
  13. if (typeof value !== 'boolean') {
  14. throw new Error(`Preset react-app: '${name}' option must be a boolean.`);
  15. }
  16. return value;
  17. };
  18. module.exports = function (api, opts, env) {
  19. if (!opts) {
  20. opts = {};
  21. }
  22. var isEnvDevelopment = env === 'development';
  23. var isEnvProduction = env === 'production';
  24. var isEnvTest = env === 'test';
  25. var useESModules = validateBoolOption(
  26. 'useESModules',
  27. opts.useESModules,
  28. isEnvDevelopment || isEnvProduction
  29. );
  30. var isFlowEnabled = validateBoolOption('flow', opts.flow, true);
  31. var isTypeScriptEnabled = validateBoolOption(
  32. 'typescript',
  33. opts.typescript,
  34. true
  35. );
  36. var areHelpersEnabled = validateBoolOption('helpers', opts.helpers, true);
  37. var useAbsoluteRuntime = validateBoolOption(
  38. 'absoluteRuntime',
  39. opts.absoluteRuntime,
  40. true
  41. );
  42. var absoluteRuntimePath = undefined;
  43. if (useAbsoluteRuntime) {
  44. absoluteRuntimePath = path.dirname(
  45. require.resolve('@babel/runtime/package.json')
  46. );
  47. }
  48. if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) {
  49. throw new Error(
  50. 'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' +
  51. '`BABEL_ENV` environment variables. Valid values are "development", ' +
  52. '"test", and "production". Instead, received: ' +
  53. JSON.stringify(env) +
  54. '.'
  55. );
  56. }
  57. return {
  58. presets: [
  59. isEnvTest && [
  60. // ES features necessary for user's Node version
  61. require('@babel/preset-env').default,
  62. {
  63. targets: {
  64. node: 'current',
  65. },
  66. },
  67. ],
  68. (isEnvProduction || isEnvDevelopment) && [
  69. // Latest stable ECMAScript features
  70. require('@babel/preset-env').default,
  71. {
  72. // Allow importing core-js in entrypoint and use browserlist to select polyfills
  73. useBuiltIns: 'entry',
  74. // Set the corejs version we are using to avoid warnings in console
  75. corejs: 3,
  76. // Exclude transforms that make all code slower
  77. exclude: ['transform-typeof-symbol'],
  78. },
  79. ],
  80. [
  81. require('@babel/preset-react').default,
  82. {
  83. // Adds component stack to warning messages
  84. // Adds __self attribute to JSX which React will use for some warnings
  85. development: isEnvDevelopment || isEnvTest,
  86. // Will use the native built-in instead of trying to polyfill
  87. // behavior for any plugins that require one.
  88. ...(opts.runtime !== 'automatic' ? { useBuiltIns: true } : {}),
  89. runtime: opts.runtime || 'classic',
  90. },
  91. ],
  92. isTypeScriptEnabled && [require('@babel/preset-typescript').default],
  93. ].filter(Boolean),
  94. plugins: [
  95. // Strip flow types before any other transform, emulating the behavior
  96. // order as-if the browser supported all of the succeeding features
  97. // https://github.com/facebook/create-react-app/pull/5182
  98. // We will conditionally enable this plugin below in overrides as it clashes with
  99. // @babel/plugin-proposal-decorators when using TypeScript.
  100. // https://github.com/facebook/create-react-app/issues/5741
  101. isFlowEnabled && [
  102. require('@babel/plugin-transform-flow-strip-types').default,
  103. false,
  104. ],
  105. // Experimental macros support. Will be documented after it's had some time
  106. // in the wild.
  107. require('babel-plugin-macros'),
  108. // Disabled as it's handled automatically by preset-env, and `selectiveLoose` isn't
  109. // yet merged into babel: https://github.com/babel/babel/pull/9486
  110. // Related: https://github.com/facebook/create-react-app/pull/8215
  111. // [
  112. // require('@babel/plugin-transform-destructuring').default,
  113. // {
  114. // // Use loose mode for performance:
  115. // // https://github.com/facebook/create-react-app/issues/5602
  116. // loose: false,
  117. // selectiveLoose: [
  118. // 'useState',
  119. // 'useEffect',
  120. // 'useContext',
  121. // 'useReducer',
  122. // 'useCallback',
  123. // 'useMemo',
  124. // 'useRef',
  125. // 'useImperativeHandle',
  126. // 'useLayoutEffect',
  127. // 'useDebugValue',
  128. // ],
  129. // },
  130. // ],
  131. // Turn on legacy decorators for TypeScript files
  132. isTypeScriptEnabled && [
  133. require('@babel/plugin-proposal-decorators').default,
  134. false,
  135. ],
  136. // class { handleClick = () => { } }
  137. // Enable loose mode to use assignment instead of defineProperty
  138. // See discussion in https://github.com/facebook/create-react-app/issues/4263
  139. [
  140. require('@babel/plugin-proposal-class-properties').default,
  141. {
  142. loose: true,
  143. },
  144. ],
  145. // Adds Numeric Separators
  146. require('@babel/plugin-proposal-numeric-separator').default,
  147. // Polyfills the runtime needed for async/await, generators, and friends
  148. // https://babeljs.io/docs/en/babel-plugin-transform-runtime
  149. [
  150. require('@babel/plugin-transform-runtime').default,
  151. {
  152. corejs: false,
  153. helpers: areHelpersEnabled,
  154. // By default, babel assumes babel/runtime version 7.0.0-beta.0,
  155. // explicitly resolving to match the provided helper functions.
  156. // https://github.com/babel/babel/issues/10261
  157. version: require('@babel/runtime/package.json').version,
  158. regenerator: true,
  159. // https://babeljs.io/docs/en/babel-plugin-transform-runtime#useesmodules
  160. // We should turn this on once the lowest version of Node LTS
  161. // supports ES Modules.
  162. useESModules,
  163. // Undocumented option that lets us encapsulate our runtime, ensuring
  164. // the correct version is used
  165. // https://github.com/babel/babel/blob/090c364a90fe73d36a30707fc612ce037bdbbb24/packages/babel-plugin-transform-runtime/src/index.js#L35-L42
  166. absoluteRuntime: absoluteRuntimePath,
  167. },
  168. ],
  169. isEnvProduction && [
  170. // Remove PropTypes from production build
  171. require('babel-plugin-transform-react-remove-prop-types').default,
  172. {
  173. removeImport: true,
  174. },
  175. ],
  176. // Optional chaining and nullish coalescing are supported in @babel/preset-env,
  177. // but not yet supported in webpack due to support missing from acorn.
  178. // These can be removed once webpack has support.
  179. // See https://github.com/facebook/create-react-app/issues/8445#issuecomment-588512250
  180. require('@babel/plugin-proposal-optional-chaining').default,
  181. require('@babel/plugin-proposal-nullish-coalescing-operator').default,
  182. ].filter(Boolean),
  183. overrides: [
  184. isFlowEnabled && {
  185. exclude: /\.tsx?$/,
  186. plugins: [require('@babel/plugin-transform-flow-strip-types').default],
  187. },
  188. isTypeScriptEnabled && {
  189. test: /\.tsx?$/,
  190. plugins: [
  191. [
  192. require('@babel/plugin-proposal-decorators').default,
  193. { legacy: true },
  194. ],
  195. ],
  196. },
  197. ].filter(Boolean),
  198. };
  199. };