UNPKG

5.38 kBJavaScriptView Raw
1import { createBabelInputPluginFactory } from '@rollup/plugin-babel';
2import merge from 'lodash.merge';
3import transformFastRest from './transform-fast-rest';
4import { isTruthy } from '../utils';
5
6const ESMODULES_TARGET = {
7 esmodules: true,
8};
9
10const mergeConfigItems = (babel, type, ...configItemsToMerge) => {
11 const mergedItems = [];
12
13 configItemsToMerge.forEach(configItemToMerge => {
14 configItemToMerge.forEach(item => {
15 const itemToMergeWithIndex = mergedItems.findIndex(
16 mergedItem =>
17 (mergedItem.name || mergedItem.file.resolved) ===
18 (item.name || item.file.resolved),
19 );
20
21 if (itemToMergeWithIndex === -1) {
22 mergedItems.push(item);
23 return;
24 }
25
26 mergedItems[itemToMergeWithIndex] = babel.createConfigItem(
27 [
28 mergedItems[itemToMergeWithIndex].file.resolved,
29 merge(mergedItems[itemToMergeWithIndex].options, item.options),
30 ],
31 {
32 type,
33 },
34 );
35 });
36 });
37
38 return mergedItems;
39};
40
41const createConfigItems = (babel, type, items) => {
42 return items.map(item => {
43 let { name, value, ...options } = item;
44 value = value || [require.resolve(name), options];
45 return babel.createConfigItem(value, { type });
46 });
47};
48
49const environmentPreset = '@babel/preset-env';
50// capture both @babel/env & @babel/preset-env (https://babeljs.io/docs/en/presets#preset-shorthand)
51const presetEnvRegex = new RegExp(/@babel\/(preset-)?env/);
52
53export default () => {
54 return createBabelInputPluginFactory(babelCore => {
55 return {
56 // Passed the plugin options.
57 options({ custom: customOptions, ...pluginOptions }) {
58 return {
59 // Pull out any custom options that the plugin might have.
60 customOptions,
61
62 // Pass the options back with the two custom options removed.
63 pluginOptions,
64 };
65 },
66
67 config(config, { customOptions }) {
68 const targets = customOptions.targets;
69 const isNodeTarget = targets && targets.node != null;
70
71 const defaultPlugins = createConfigItems(
72 babelCore,
73 'plugin',
74 [
75 {
76 name: '@babel/plugin-syntax-import-meta',
77 },
78 !customOptions.jsxImportSource && {
79 name: '@babel/plugin-transform-react-jsx',
80 pragma: customOptions.pragma || 'h',
81 pragmaFrag: customOptions.pragmaFrag || 'Fragment',
82 },
83 !customOptions.typescript && {
84 name: '@babel/plugin-transform-flow-strip-types',
85 },
86 isTruthy(customOptions.defines) && {
87 name: 'babel-plugin-transform-replace-expressions',
88 replace: customOptions.defines,
89 },
90 !customOptions.modern &&
91 !isNodeTarget && {
92 name: 'babel-plugin-transform-async-to-promises',
93 inlineHelpers: true,
94 externalHelpers: false,
95 minify: true,
96 },
97 !customOptions.modern &&
98 !isNodeTarget && {
99 value: [
100 transformFastRest,
101 {
102 // Use inline [].slice.call(arguments)
103 helper: false,
104 literal: true,
105 },
106 'transform-fast-rest',
107 ],
108 },
109 {
110 name: '@babel/plugin-proposal-class-properties',
111 loose: true,
112 },
113 !customOptions.modern &&
114 !isNodeTarget && {
115 name: '@babel/plugin-transform-regenerator',
116 async: false,
117 },
118 {
119 name: 'babel-plugin-macros',
120 },
121 ].filter(Boolean),
122 );
123
124 const babelOptions = config.options || {};
125
126 const envIdx = (babelOptions.presets || []).findIndex(preset =>
127 presetEnvRegex.test(preset.file.request),
128 );
129
130 if (envIdx !== -1) {
131 const preset = babelOptions.presets[envIdx];
132 babelOptions.presets[envIdx] = babelCore.createConfigItem(
133 [
134 require.resolve(environmentPreset),
135 Object.assign(
136 merge(
137 {
138 loose: true,
139 useBuiltIns: false,
140 targets: customOptions.targets,
141 },
142 preset.options,
143 {
144 bugfixes: customOptions.modern,
145 modules: false,
146 exclude: merge(
147 ['transform-async-to-generator', 'transform-regenerator'],
148 (preset.options && preset.options.exclude) || [],
149 ),
150 },
151 ),
152 customOptions.modern ? { targets: ESMODULES_TARGET } : {},
153 ),
154 ],
155 {
156 type: `preset`,
157 },
158 );
159 } else {
160 babelOptions.presets = createConfigItems(
161 babelCore,
162 'preset',
163 [
164 {
165 name: environmentPreset,
166 targets: customOptions.modern
167 ? ESMODULES_TARGET
168 : customOptions.targets,
169 modules: false,
170 loose: true,
171 useBuiltIns: false,
172 bugfixes: customOptions.modern,
173 exclude: [
174 'transform-async-to-generator',
175 'transform-regenerator',
176 ],
177 },
178 customOptions.jsxImportSource && {
179 name: '@babel/preset-react',
180 runtime: 'automatic',
181 importSource: customOptions.jsxImportSource,
182 },
183 ].filter(Boolean),
184 );
185 }
186
187 // Merge babelrc & our plugins together
188 babelOptions.plugins = mergeConfigItems(
189 babelCore,
190 'plugin',
191 defaultPlugins,
192 babelOptions.plugins || [],
193 );
194
195 if (customOptions.compress) {
196 babelOptions.generatorOpts = {
197 minified: true,
198 compact: true,
199 shouldPrintComment: comment => /[@#]__PURE__/.test(comment),
200 };
201 }
202
203 return babelOptions;
204 },
205 };
206 });
207};