1 | import { createBabelInputPluginFactory } from '@rollup/plugin-babel';
|
2 | import merge from 'lodash.merge';
|
3 | import transformFastRest from './transform-fast-rest';
|
4 | import { isTruthy } from '../utils';
|
5 |
|
6 | const ESMODULES_TARGET = {
|
7 | esmodules: true,
|
8 | };
|
9 |
|
10 | const 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 |
|
41 | const 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 |
|
49 | const environmentPreset = '@babel/preset-env';
|
50 |
|
51 | const presetEnvRegex = new RegExp(/@babel\/(preset-)?env/);
|
52 |
|
53 | export default () => {
|
54 | return createBabelInputPluginFactory(babelCore => {
|
55 | return {
|
56 |
|
57 | options({ custom: customOptions, ...pluginOptions }) {
|
58 | return {
|
59 |
|
60 | customOptions,
|
61 |
|
62 |
|
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 |
|
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 |
|
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 | };
|