UNPKG

16.5 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var babel = require('@babel/core');
6var pluginutils = require('@rollup/pluginutils');
7var helperModuleImports = require('@babel/helper-module-imports');
8
9function _interopNamespace(e) {
10 if (e && e.__esModule) return e;
11 var n = Object.create(null);
12 if (e) {
13 Object.keys(e).forEach(function (k) {
14 if (k !== 'default') {
15 var d = Object.getOwnPropertyDescriptor(e, k);
16 Object.defineProperty(n, k, d.get ? d : {
17 enumerable: true,
18 get: function () { return e[k]; }
19 });
20 }
21 });
22 }
23 n["default"] = e;
24 return Object.freeze(n);
25}
26
27var babel__namespace = /*#__PURE__*/_interopNamespace(babel);
28
29function _defineProperty(obj, key, value) {
30 if (key in obj) {
31 Object.defineProperty(obj, key, {
32 value: value,
33 enumerable: true,
34 configurable: true,
35 writable: true
36 });
37 } else {
38 obj[key] = value;
39 }
40
41 return obj;
42}
43
44function ownKeys(object, enumerableOnly) {
45 var keys = Object.keys(object);
46
47 if (Object.getOwnPropertySymbols) {
48 var symbols = Object.getOwnPropertySymbols(object);
49 if (enumerableOnly) symbols = symbols.filter(function (sym) {
50 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
51 });
52 keys.push.apply(keys, symbols);
53 }
54
55 return keys;
56}
57
58function _objectSpread2(target) {
59 for (var i = 1; i < arguments.length; i++) {
60 var source = arguments[i] != null ? arguments[i] : {};
61
62 if (i % 2) {
63 ownKeys(Object(source), true).forEach(function (key) {
64 _defineProperty(target, key, source[key]);
65 });
66 } else if (Object.getOwnPropertyDescriptors) {
67 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
68 } else {
69 ownKeys(Object(source)).forEach(function (key) {
70 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
71 });
72 }
73 }
74
75 return target;
76}
77
78function _objectWithoutPropertiesLoose(source, excluded) {
79 if (source == null) return {};
80 var target = {};
81 var sourceKeys = Object.keys(source);
82 var key, i;
83
84 for (i = 0; i < sourceKeys.length; i++) {
85 key = sourceKeys[i];
86 if (excluded.indexOf(key) >= 0) continue;
87 target[key] = source[key];
88 }
89
90 return target;
91}
92
93function _objectWithoutProperties(source, excluded) {
94 if (source == null) return {};
95
96 var target = _objectWithoutPropertiesLoose(source, excluded);
97
98 var key, i;
99
100 if (Object.getOwnPropertySymbols) {
101 var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
102
103 for (i = 0; i < sourceSymbolKeys.length; i++) {
104 key = sourceSymbolKeys[i];
105 if (excluded.indexOf(key) >= 0) continue;
106 if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
107 target[key] = source[key];
108 }
109 }
110
111 return target;
112}
113
114const BUNDLED = 'bundled';
115const INLINE = 'inline';
116const RUNTIME = 'runtime';
117const EXTERNAL = 'external'; // NOTE: DO NOT REMOVE the null character `\0` as it may be used by other plugins
118// e.g. https://github.com/rollup/rollup-plugin-node-resolve/blob/313a3e32f432f9eb18cc4c231cc7aac6df317a51/src/index.js#L74
119
120const HELPERS = '\0rollupPluginBabelHelpers.js';
121
122function importHelperPlugin({
123 types: t
124}) {
125 return {
126 pre(file) {
127 const cachedHelpers = {};
128 file.set('helperGenerator', name => {
129 if (!file.availableHelper(name)) {
130 return null;
131 }
132
133 if (cachedHelpers[name]) {
134 return t.cloneNode(cachedHelpers[name]);
135 }
136
137 return cachedHelpers[name] = helperModuleImports.addNamed(file.path, name, HELPERS);
138 });
139 }
140
141 };
142}
143
144const addBabelPlugin = (options, plugin) => {
145 return _objectSpread2(_objectSpread2({}, options), {}, {
146 plugins: options.plugins.concat(plugin)
147 });
148};
149const warned = {};
150function warnOnce(ctx, msg) {
151 if (warned[msg]) return;
152 warned[msg] = true;
153 ctx.warn(msg);
154}
155const regExpCharactersRegExp = /[\\^$.*+?()[\]{}|]/g;
156const escapeRegExpCharacters = str => str.replace(regExpCharactersRegExp, '\\$&');
157function stripQuery(id) {
158 // strip query params from import
159 const [bareId, query] = id.split('?');
160 const suffix = `${query ? `?${query}` : ''}`;
161 return {
162 bareId,
163 query,
164 suffix
165 };
166}
167
168const MODULE_ERROR = 'Rollup requires that your Babel configuration keeps ES6 module syntax intact. ' + 'Unfortunately it looks like your configuration specifies a module transformer ' + 'to replace ES6 modules with another module format. To continue you have to disable it.' + '\n\n' + "Most commonly it's a CommonJS transform added by @babel/preset-env - " + 'in such case you should disable it by adding `modules: false` option to that preset ' + '(described in more detail here - https://github.com/rollup/plugins/tree/master/packages/babel#modules ).';
169const UNEXPECTED_ERROR = 'An unexpected situation arose. Please raise an issue at ' + 'https://github.com/rollup/plugins/issues. Thanks!';
170const PREFLIGHT_TEST_STRING = '__ROLLUP__PREFLIGHT_CHECK_DO_NOT_TOUCH__';
171const PREFLIGHT_INPUT = `export default "${PREFLIGHT_TEST_STRING}";`;
172
173function helpersTestTransform() {
174 return {
175 visitor: {
176 StringLiteral(path, state) {
177 if (path.node.value === PREFLIGHT_TEST_STRING) {
178 path.replaceWith(state.file.addHelper('inherits'));
179 }
180 }
181
182 }
183 };
184}
185
186const mismatchError = (actual, expected, filename) => `You have declared using "${expected}" babelHelpers, but transforming ${filename} resulted in "${actual}". Please check your configuration.`; // Revert to /\/helpers\/(esm\/)?inherits/ when Babel 8 gets released, this was fixed in https://github.com/babel/babel/issues/14185
187
188
189const inheritsHelperRe = /[\\/]+helpers[\\/]+(esm[\\/]+)?inherits/;
190async function preflightCheck(ctx, babelHelpers, transformOptions) {
191 const finalOptions = addBabelPlugin(transformOptions, helpersTestTransform);
192 const check = (await babel__namespace.transformAsync(PREFLIGHT_INPUT, finalOptions)).code; // Babel sometimes splits ExportDefaultDeclaration into 2 statements, so we also check for ExportNamedDeclaration
193
194 if (!/export (d|{)/.test(check)) {
195 ctx.error(MODULE_ERROR);
196 }
197
198 if (inheritsHelperRe.test(check)) {
199 if (babelHelpers === RUNTIME) {
200 return;
201 }
202
203 ctx.error(mismatchError(RUNTIME, babelHelpers, transformOptions.filename));
204 }
205
206 if (check.includes('babelHelpers.inherits')) {
207 if (babelHelpers === EXTERNAL) {
208 return;
209 }
210
211 ctx.error(mismatchError(EXTERNAL, babelHelpers, transformOptions.filename));
212 } // test unminifiable string content
213
214
215 if (check.includes('Super expression must either be null or a function')) {
216 if (babelHelpers === INLINE || babelHelpers === BUNDLED) {
217 return;
218 }
219
220 if (babelHelpers === RUNTIME && !transformOptions.plugins.length) {
221 ctx.error(`You must use the \`@babel/plugin-transform-runtime\` plugin when \`babelHelpers\` is "${RUNTIME}".\n`);
222 }
223
224 ctx.error(mismatchError(INLINE, babelHelpers, transformOptions.filename));
225 }
226
227 ctx.error(UNEXPECTED_ERROR);
228}
229
230async function transformCode(inputCode, babelOptions, overrides, customOptions, ctx, finalizeOptions) {
231 // loadPartialConfigAsync has become available in @babel/core@7.8.0
232 const config = await (babel__namespace.loadPartialConfigAsync || babel__namespace.loadPartialConfig)(babelOptions); // file is ignored by babel
233
234 if (!config) {
235 return null;
236 }
237
238 let transformOptions = !overrides.config ? config.options : await overrides.config.call(ctx, config, {
239 code: inputCode,
240 customOptions
241 });
242
243 if (finalizeOptions) {
244 transformOptions = await finalizeOptions(transformOptions);
245 }
246
247 if (!overrides.result) {
248 const {
249 code,
250 map
251 } = await babel__namespace.transformAsync(inputCode, transformOptions);
252 return {
253 code,
254 map
255 };
256 }
257
258 const result = await babel__namespace.transformAsync(inputCode, transformOptions);
259 const {
260 code,
261 map
262 } = await overrides.result.call(ctx, result, {
263 code: inputCode,
264 customOptions,
265 config,
266 transformOptions
267 });
268 return {
269 code,
270 map
271 };
272}
273
274const unpackOptions = (_ref = {}) => {
275 let {
276 extensions = babel__namespace.DEFAULT_EXTENSIONS,
277 // rollup uses sourcemap, babel uses sourceMaps
278 // just normalize them here so people don't have to worry about it
279 sourcemap = true,
280 sourcemaps = true,
281 sourceMap = true,
282 sourceMaps = true
283 } = _ref,
284 rest = _objectWithoutProperties(_ref, ["extensions", "sourcemap", "sourcemaps", "sourceMap", "sourceMaps"]);
285
286 return _objectSpread2(_objectSpread2({
287 extensions,
288 plugins: [],
289 sourceMaps: sourcemap && sourcemaps && sourceMap && sourceMaps
290 }, rest), {}, {
291 caller: _objectSpread2({
292 name: '@rollup/plugin-babel'
293 }, rest.caller)
294 });
295};
296
297const warnAboutDeprecatedHelpersOption = ({
298 deprecatedOption,
299 suggestion
300}) => {
301 // eslint-disable-next-line no-console
302 console.warn(`\`${deprecatedOption}\` has been removed in favor a \`babelHelpers\` option. Try changing your configuration to \`${suggestion}\`. ` + `Refer to the documentation to learn more: https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers`);
303};
304
305const unpackInputPluginOptions = (_ref2, rollupVersion) => {
306 let {
307 skipPreflightCheck = false
308 } = _ref2,
309 rest = _objectWithoutProperties(_ref2, ["skipPreflightCheck"]);
310
311 if ('runtimeHelpers' in rest) {
312 warnAboutDeprecatedHelpersOption({
313 deprecatedOption: 'runtimeHelpers',
314 suggestion: `babelHelpers: 'runtime'`
315 });
316 } else if ('externalHelpers' in rest) {
317 warnAboutDeprecatedHelpersOption({
318 deprecatedOption: 'externalHelpers',
319 suggestion: `babelHelpers: 'external'`
320 });
321 } else if (!rest.babelHelpers) {
322 // eslint-disable-next-line no-console
323 console.warn("babelHelpers: 'bundled' option was used by default. It is recommended to configure this option explicitly, read more here: " + 'https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers');
324 }
325
326 return unpackOptions(_objectSpread2(_objectSpread2({}, rest), {}, {
327 skipPreflightCheck,
328 babelHelpers: rest.babelHelpers || BUNDLED,
329 caller: _objectSpread2({
330 supportsStaticESM: true,
331 supportsDynamicImport: true,
332 supportsTopLevelAwait: true,
333 // todo: remove version checks for 1.20 - 1.25 when we bump peer deps
334 supportsExportNamespaceFrom: !rollupVersion.match(/^1\.2[0-5]\./)
335 }, rest.caller)
336 }));
337};
338
339const unpackOutputPluginOptions = (options, {
340 format
341}) => unpackOptions(_objectSpread2(_objectSpread2({
342 configFile: false,
343 sourceType: format === 'es' ? 'module' : 'script'
344}, options), {}, {
345 caller: _objectSpread2({
346 supportsStaticESM: format === 'es'
347 }, options.caller)
348}));
349
350function getOptionsWithOverrides(pluginOptions = {}, overrides = {}) {
351 if (!overrides.options) return {
352 customOptions: null,
353 pluginOptionsWithOverrides: pluginOptions
354 };
355 const overridden = overrides.options(pluginOptions);
356
357 if (typeof overridden.then === 'function') {
358 throw new Error(".options hook can't be asynchronous. It should return `{ customOptions, pluginsOptions }` synchronously.");
359 }
360
361 return {
362 customOptions: overridden.customOptions || null,
363 pluginOptionsWithOverrides: overridden.pluginOptions || pluginOptions
364 };
365}
366
367const returnObject = () => {
368 return {};
369};
370
371function createBabelInputPluginFactory(customCallback = returnObject) {
372 const overrides = customCallback(babel__namespace);
373 return pluginOptions => {
374 const {
375 customOptions,
376 pluginOptionsWithOverrides
377 } = getOptionsWithOverrides(pluginOptions, overrides);
378 let babelHelpers;
379 let babelOptions;
380 let filter;
381 let skipPreflightCheck;
382 return {
383 name: 'babel',
384
385 options() {
386 // todo: remove options hook and hoist declarations when version checks are removed
387 let exclude;
388 let include;
389 let extensions;
390 let customFilter;
391
392 var _unpackInputPluginOpt = unpackInputPluginOptions(pluginOptionsWithOverrides, this.meta.rollupVersion);
393
394 ({
395 exclude,
396 extensions,
397 babelHelpers,
398 include,
399 filter: customFilter,
400 skipPreflightCheck
401 } = _unpackInputPluginOpt);
402 babelOptions = _objectWithoutProperties(_unpackInputPluginOpt, ["exclude", "extensions", "babelHelpers", "include", "filter", "skipPreflightCheck"]);
403 const extensionRegExp = new RegExp(`(${extensions.map(escapeRegExpCharacters).join('|')})$`);
404
405 if (customFilter && (include || exclude)) {
406 throw new Error('Could not handle include or exclude with custom filter together');
407 }
408
409 const userDefinedFilter = typeof customFilter === 'function' ? customFilter : pluginutils.createFilter(include, exclude);
410
411 filter = id => extensionRegExp.test(stripQuery(id).bareId) && userDefinedFilter(id);
412
413 return null;
414 },
415
416 resolveId(id) {
417 if (id !== HELPERS) {
418 return null;
419 }
420
421 return id;
422 },
423
424 load(id) {
425 if (id !== HELPERS) {
426 return null;
427 }
428
429 return babel__namespace.buildExternalHelpers(null, 'module');
430 },
431
432 transform(code, filename) {
433 if (!filter(filename)) return null;
434 if (filename === HELPERS) return null;
435 return transformCode(code, _objectSpread2(_objectSpread2({}, babelOptions), {}, {
436 filename
437 }), overrides, customOptions, this, async transformOptions => {
438 if (!skipPreflightCheck) {
439 await preflightCheck(this, babelHelpers, transformOptions);
440 }
441
442 return babelHelpers === BUNDLED ? addBabelPlugin(transformOptions, importHelperPlugin) : transformOptions;
443 });
444 }
445
446 };
447 };
448}
449
450function getRecommendedFormat(rollupFormat) {
451 switch (rollupFormat) {
452 case 'amd':
453 return 'amd';
454
455 case 'iife':
456 case 'umd':
457 return 'umd';
458
459 case 'system':
460 return 'systemjs';
461
462 default:
463 return '<module format>';
464 }
465}
466
467function createBabelOutputPluginFactory(customCallback = returnObject) {
468 const overrides = customCallback(babel__namespace);
469 return pluginOptions => {
470 const {
471 customOptions,
472 pluginOptionsWithOverrides
473 } = getOptionsWithOverrides(pluginOptions, overrides);
474 return {
475 name: 'babel',
476
477 renderStart(outputOptions) {
478 const {
479 extensions,
480 include,
481 exclude,
482 allowAllFormats
483 } = pluginOptionsWithOverrides;
484
485 if (extensions || include || exclude) {
486 warnOnce(this, 'The "include", "exclude" and "extensions" options are ignored when transforming the output.');
487 }
488
489 if (!allowAllFormats && outputOptions.format !== 'es' && outputOptions.format !== 'cjs') {
490 this.error(`Using Babel on the generated chunks is strongly discouraged for formats other than "esm" or "cjs" as it can easily break wrapper code and lead to accidentally created global variables. Instead, you should set "output.format" to "esm" and use Babel to transform to another format, e.g. by adding "presets: [['@babel/env', { modules: '${getRecommendedFormat(outputOptions.format)}' }]]" to your Babel options. If you still want to proceed, add "allowAllFormats: true" to your plugin options.`);
491 }
492 },
493
494 renderChunk(code, chunk, outputOptions) {
495 /* eslint-disable no-unused-vars */
496 const _unpackOutputPluginOp = unpackOutputPluginOptions(pluginOptionsWithOverrides, outputOptions),
497 babelOptions = _objectWithoutProperties(_unpackOutputPluginOp, ["allowAllFormats", "exclude", "extensions", "externalHelpers", "externalHelpersWhitelist", "include", "runtimeHelpers"]);
498 /* eslint-enable no-unused-vars */
499
500
501 return transformCode(code, babelOptions, overrides, customOptions, this);
502 }
503
504 };
505 };
506} // export this for symmetry with output-related exports
507
508
509const getBabelInputPlugin = createBabelInputPluginFactory();
510const getBabelOutputPlugin = createBabelOutputPluginFactory();
511
512exports.babel = getBabelInputPlugin;
513exports.createBabelInputPluginFactory = createBabelInputPluginFactory;
514exports.createBabelOutputPluginFactory = createBabelOutputPluginFactory;
515exports["default"] = getBabelInputPlugin;
516exports.getBabelInputPlugin = getBabelInputPlugin;
517exports.getBabelOutputPlugin = getBabelOutputPlugin;