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 presetEnvRegex = RegExp(/@babel\/(preset-)?env/);
|
50 |
|
51 | export default () => {
|
52 | return createBabelInputPluginFactory(babelCore => {
|
53 | return {
|
54 |
|
55 | options({ custom: customOptions, ...pluginOptions }) {
|
56 | return {
|
57 |
|
58 | customOptions,
|
59 |
|
60 |
|
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 |
|
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 |
|
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 | };
|