index.js 4.67 KB
Newer Older
1
2
3
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
Sophie Alpert's avatar
Sophie Alpert committed
4
5
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
6
7
8
 */
'use strict';

9
10
11
12
13
14
15
16
17
18
19
20
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;
};

Clement Hoang's avatar
Clement Hoang committed
21
22
23
24
module.exports = function(api, opts) {
  if (!opts) {
    opts = {};
  }
25

Clement Hoang's avatar
Clement Hoang committed
26
27
28
29
30
31
32
33
34
35
  // 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/facebookincubator/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';
36
37
  var isFlowEnabled = validateBoolOption('flow', opts.flow, true);

Clement Hoang's avatar
Clement Hoang committed
38
39
40
41
42
43
44
45
46
  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) +
        '.'
    );
  }
47

Clement Hoang's avatar
Clement Hoang committed
48
  return {
49
    presets: [
Clement Hoang's avatar
Clement Hoang committed
50
51
52
      isEnvTest && [
        // ES features necessary for user's Node version
        require('@babel/preset-env').default,
53
54
        {
          targets: {
Clement Hoang's avatar
Clement Hoang committed
55
            node: '6.12',
56
          },
57
        },
58
      ],
Clement Hoang's avatar
Clement Hoang committed
59
60
61
      (isEnvProduction || isEnvDevelopment) && [
        // Latest stable ECMAScript features
        require('@babel/preset-env').default,
62
        {
63
64
65
66
67
68
          // `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',
69
70
          // Do not transform modules to CJS
          modules: false,
Joe Haddad's avatar
Joe Haddad committed
71
        },
72
73
      ],
      [
Clement Hoang's avatar
Clement Hoang committed
74
75
76
77
78
79
80
        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,
        },
      ],
81
      isFlowEnabled && [require('@babel/preset-flow').default],
Clement Hoang's avatar
Clement Hoang committed
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
    ].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 = () => { } }
      require('@babel/plugin-proposal-class-properties').default,
      // 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,
        },
      ],
      // Transforms JSX
      [
        require('@babel/plugin-transform-react-jsx').default,
        {
          useBuiltIns: true,
        },
      ],
      // Polyfills the runtime needed for async/await and generators
      [
        require('@babel/plugin-transform-runtime').default,
        {
          helpers: false,
          polyfill: false,
          regenerator: true,
        },
      ],
118
119
120
121
122
123
124
      isEnvProduction && [
        // Remove PropTypes from production build
        require('babel-plugin-transform-react-remove-prop-types').default,
        {
          removeImport: true,
        },
      ],
Clement Hoang's avatar
Clement Hoang committed
125
126
127
      // function* () { yield 42; yield 43; }
      !isEnvTest && [
        require('@babel/plugin-transform-regenerator').default,
128
        {
129
          // Async functions are converted to generators by @babel/preset-env
130
131
132
          async: false,
        },
      ],
133
      // Adds syntax support for import()
Clement Hoang's avatar
Clement Hoang committed
134
135
136
137
138
      require('@babel/plugin-syntax-dynamic-import').default,
      isEnvTest &&
        // Transform dynamic import to require
        require('babel-plugin-transform-dynamic-import').default,
    ].filter(Boolean),
139
  };
Clement Hoang's avatar
Clement Hoang committed
140
};