UNPKG

4.94 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 presetEnvRegex = RegExp(/@babel\/(preset-)?env/);
50
51export default () => {
52 return createBabelInputPluginFactory(babelCore => {
53 return {
54 // Passed the plugin options.
55 options({ custom: customOptions, ...pluginOptions }) {
56 return {
57 // Pull out any custom options that the plugin might have.
58 customOptions,
59
60 // Pass the options back with the two custom options removed.
61 pluginOptions,
62 };
63 },
64
65 config(config, { customOptions }) {
66 const targets = customOptions.targets;
67 const isNodeTarget = targets && targets.node != null;
68
69 const defaultPlugins = createConfigItems(
70 babelCore,
71 'plugin',
72 [
73 {
74 name: '@babel/plugin-syntax-import-meta',
75 },
76 {
77 name: '@babel/plugin-transform-react-jsx',
78 pragma: customOptions.pragma || 'h',
79 pragmaFrag: customOptions.pragmaFrag || 'Fragment',
80 },
81 !customOptions.typescript && {
82 name: '@babel/plugin-transform-flow-strip-types',
83 },
84 isTruthy(customOptions.defines) && {
85 name: 'babel-plugin-transform-replace-expressions',
86 replace: customOptions.defines,
87 },
88 !customOptions.modern && {
89 name: 'babel-plugin-transform-async-to-promises',
90 inlineHelpers: true,
91 externalHelpers: false,
92 minify: true,
93 },
94 !customOptions.modern &&
95 !isNodeTarget && {
96 value: [
97 transformFastRest,
98 {
99 // Use inline [].slice.call(arguments)
100 helper: false,
101 literal: true,
102 },
103 'transform-fast-rest',
104 ],
105 },
106 {
107 name: '@babel/plugin-proposal-class-properties',
108 loose: true,
109 },
110 !customOptions.modern && {
111 name: '@babel/plugin-transform-regenerator',
112 async: false,
113 },
114 {
115 name: 'babel-plugin-macros',
116 },
117 ].filter(Boolean),
118 );
119
120 const babelOptions = config.options || {};
121
122 const envIdx = (babelOptions.presets || []).findIndex(preset =>
123 presetEnvRegex.test(preset.file.request),
124 );
125
126 const environmentPreset = customOptions.modern
127 ? '@babel/preset-modules'
128 : '@babel/preset-env';
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 modules: false,
145 exclude: merge(
146 ['transform-async-to-generator', 'transform-regenerator'],
147 (preset.options && preset.options.exclude) || [],
148 ),
149 },
150 ),
151 customOptions.modern ? { targets: ESMODULES_TARGET } : {},
152 ),
153 ],
154 {
155 type: `preset`,
156 },
157 );
158 } else {
159 babelOptions.presets = createConfigItems(babelCore, 'preset', [
160 {
161 name: environmentPreset,
162 targets: customOptions.modern
163 ? ESMODULES_TARGET
164 : customOptions.targets,
165 modules: false,
166 loose: true,
167 useBuiltIns: false,
168 exclude: [
169 'transform-async-to-generator',
170 'transform-regenerator',
171 ],
172 },
173 ]);
174 }
175
176 // Merge babelrc & our plugins together
177 babelOptions.plugins = mergeConfigItems(
178 babelCore,
179 'plugin',
180 defaultPlugins,
181 babelOptions.plugins || [],
182 );
183
184 if (customOptions.compress) {
185 babelOptions.generatorOpts = {
186 minified: true,
187 compact: true,
188 shouldPrintComment: comment => /[@#]__PURE__/.test(comment),
189 };
190 }
191
192 return babelOptions;
193 },
194 };
195 });
196};