UNPKG

4.58 kBJavaScriptView Raw
1/** Copyright (c) 2018 Uber Technologies, Inc.
2 *
3 * This source code is licensed under the MIT license found in the
4 * LICENSE file in the root directory of this source tree.
5 *
6 * @flow
7 */
8/* eslint-env node */
9const modernBrowserVersions = require('./modern-browser-versions.js');
10
11/*::
12type Target = "node-native" | "node-bundled" | "browser-modern" | "browser-legacy";
13type JSXTransformOpts = {
14 pragma?: string,
15 pragmaFrag?: string,
16};
17type BabelConfigOpts =
18| {|
19 specOnly: true,
20 target: Target,
21 plugins?: Array<any>,
22 presets?: Array<any>,
23 |}
24| {|
25 specOnly: false,
26 dev: boolean,
27 target: Target,
28 plugins?: Array<any>,
29 presets?: Array<any>,
30 jsx?: JSXTransformOpts,
31 assumeNoImportSideEffects?: boolean,
32 fusionTransforms: boolean
33 |};
34*/
35
36module.exports = function getBabelConfig(opts /*: BabelConfigOpts */) {
37 const {target, plugins, presets} = opts;
38
39 // Shared base env preset options
40 let envPresetOpts /*: Object*/ = {
41 useBuiltIns: 'entry',
42 corejs: '3.0.0',
43 };
44
45 // Shared base configuration
46 let config = {
47 plugins: [
48 require.resolve('@babel/plugin-syntax-dynamic-import'),
49 [
50 require.resolve('@rtsao/plugin-proposal-class-properties'),
51 {loose: false},
52 ],
53 opts.dev &&
54 require.resolve('babel-plugin-transform-styletron-display-name'),
55 ].filter(Boolean),
56 presets: [[require.resolve('@babel/preset-env'), envPresetOpts]],
57 babelrc: false,
58 };
59
60 if (opts.specOnly === false) {
61 let {jsx, assumeNoImportSideEffects, dev, fusionTransforms} = opts;
62 if (!jsx) {
63 jsx = {};
64 }
65 config.presets.push([
66 require.resolve('@babel/preset-react'),
67 {
68 pragma: jsx.pragma,
69 pragmaFrag: jsx.pragmaFrag,
70 development: dev,
71 },
72 ]);
73 config.plugins.unshift(
74 require.resolve('@babel/plugin-transform-flow-strip-types')
75 );
76 if (fusionTransforms) {
77 config.presets.push([fusionPreset, {target, assumeNoImportSideEffects}]);
78 } else {
79 config.plugins.push(require.resolve('./babel-plugins/babel-plugin-gql'));
80 }
81 }
82
83 if (target === 'node-native') {
84 envPresetOpts.modules = 'commonjs';
85 envPresetOpts.targets = {
86 node: 'current',
87 };
88 config.plugins.push(require.resolve('babel-plugin-dynamic-import-node'));
89 } else if (target === 'node-bundled') {
90 envPresetOpts.modules = false;
91 envPresetOpts.targets = {
92 node: 'current',
93 };
94 } else if (target === 'browser-modern') {
95 envPresetOpts.modules = false;
96 envPresetOpts.targets = modernBrowserVersions;
97 envPresetOpts.useBuiltIns = 'entry';
98 } else if (target === 'browser-legacy') {
99 envPresetOpts.modules = false;
100 envPresetOpts.targets = {
101 ie: 9,
102 };
103 }
104
105 if (plugins) {
106 // Note: babel plugins run first to last, so custom plugins go first
107 config.plugins.unshift(...plugins);
108 }
109
110 if (presets) {
111 // Note: babel presets run last to first, so custom plugins go last
112 config.presets.push(...presets);
113 }
114
115 return config;
116};
117
118/*::
119type FusionPresetOpts = {
120 target: Target,
121 assumeNoImportSideEffects: boolean,
122};
123*/
124
125/**
126 * This is abstracted into preset for the following reasoning:
127 * The tree shake plugin needs to run after JSX transform.
128 * However, the JSX transform is inside the React preset.
129 * Because plugins run before presets, the tree shake plugin
130 * must also live in a preset.
131 */
132function fusionPreset(
133 context /*: any */,
134 {target, assumeNoImportSideEffects} /*: FusionPresetOpts */
135) {
136 const targetEnv =
137 target === 'node-native' || target === 'node-bundled' ? 'node' : 'browser';
138
139 return {
140 plugins: [
141 require.resolve('./babel-plugins/babel-plugin-gql'),
142 require.resolve('./babel-plugins/babel-plugin-asseturl'),
143 require.resolve('./babel-plugins/babel-plugin-pure-create-plugin'),
144 require.resolve('./babel-plugins/babel-plugin-sync-chunk-ids'),
145 require.resolve('./babel-plugins/babel-plugin-sw'),
146 require.resolve('./babel-plugins/babel-plugin-sync-chunk-paths'),
147 require.resolve('./babel-plugins/babel-plugin-chunkid'),
148 require.resolve('./babel-plugins/babel-plugin-workerurl'),
149 [
150 require.resolve('babel-plugin-transform-cup-globals'),
151 {target: targetEnv},
152 ],
153 assumeNoImportSideEffects && [
154 require.resolve('babel-plugin-transform-prune-unused-imports'),
155 {
156 falsyExpressions:
157 targetEnv === 'node' ? ['__BROWSER__'] : ['__NODE__'],
158 },
159 ],
160 ].filter(Boolean),
161 };
162}