diff --git a/packages/babel-preset-env/src/index.js b/packages/babel-preset-env/src/index.js index 85a784476b83..6f297d8066c7 100644 --- a/packages/babel-preset-env/src/index.js +++ b/packages/babel-preset-env/src/index.js @@ -132,9 +132,13 @@ export default declare((api, opts) => { // TODO: Remove the 'api.caller' check eventually. Just here to prevent // unnecessary breakage in the short term for users on older betas/RCs. const shouldTransformESM = - modules !== "auto" || !api.caller || !api.caller(supportsStaticESM); + (modules !== "auto" || !api.caller || !api.caller(supportsStaticESM)) && + !exclude.plugins.has(moduleTransformations[modules]); const shouldTransformDynamicImport = - modules !== "auto" || !api.caller || !api.caller(supportsDynamicImport); + (modules !== "auto" || + !api.caller || + !api.caller(supportsDynamicImport)) && + !exclude.plugins.has("proposal-dynamic-import"); if (shouldTransformESM) { // NOTE: not giving spec here yet to avoid compatibility issues when diff --git a/packages/babel-preset-env/src/normalize-options.js b/packages/babel-preset-env/src/normalize-options.js index 76b13f5a7e39..368ee68ce12f 100644 --- a/packages/babel-preset-env/src/normalize-options.js +++ b/packages/babel-preset-env/src/normalize-options.js @@ -32,23 +32,29 @@ const validateTopLevelOptions = (options: Options) => { } }; -const allPluginsList = [ - ...Object.keys(pluginsList), +const allPluginsList = [...Object.keys(pluginsList)]; + +// NOTE: Since module plugins are handled seperatly compared to other plugins (via the "modules" option) it +// should only be possible to exclude and not include module plugins, otherwise it's possible that preset-env +// will add a module plugin twice. +const modulePlugins = [ + "proposal-dynamic-import", ...Object.keys(moduleTransformations).map(m => moduleTransformations[m]), ]; -const validIncludesAndExcludesWithoutCoreJS = new Set(allPluginsList); - -const validIncludesAndExcludesWithCoreJS2 = new Set([ - ...allPluginsList, - ...Object.keys(corejs2Polyfills), - ...defaultWebIncludes, -]); - -const validIncludesAndExcludesWithCoreJS3 = new Set([ - ...allPluginsList, - ...Object.keys(corejs3Polyfills), -]); +const getValidIncludesAndExcludes = ( + type: "include" | "exclude", + corejs: number | false, +) => + new Set([ + ...allPluginsList, + ...(type === "exclude" ? modulePlugins : []), + ...(corejs + ? corejs == 2 + ? [...Object.keys(corejs2Polyfills), ...defaultWebIncludes] + : Object.keys(corejs3Polyfills) + : []), + ]); const pluginToRegExp = (plugin: PluginListItem) => { if (plugin instanceof RegExp) return plugin; @@ -59,14 +65,14 @@ const pluginToRegExp = (plugin: PluginListItem) => { } }; -const selectPlugins = (regexp: RegExp | null, corejs: number | false) => - Array.from( - corejs - ? corejs == 2 - ? validIncludesAndExcludesWithCoreJS2 - : validIncludesAndExcludesWithCoreJS3 - : validIncludesAndExcludesWithoutCoreJS, - ).filter(item => regexp instanceof RegExp && regexp.test(item)); +const selectPlugins = ( + regexp: RegExp | null, + type: "include" | "exclude", + corejs: number | false, +) => + Array.from(getValidIncludesAndExcludes(type, corejs)).filter( + item => regexp instanceof RegExp && regexp.test(item), + ); const flatten = (array: Array>): Array => [].concat(...array); @@ -78,7 +84,7 @@ const expandIncludesAndExcludes = ( if (plugins.length === 0) return []; const selectedPlugins = plugins.map(plugin => - selectPlugins(pluginToRegExp(plugin), corejs), + selectPlugins(pluginToRegExp(plugin), type, corejs), ); const invalidRegExpList = plugins.filter( (p, i) => selectedPlugins[i].length === 0, diff --git a/packages/babel-preset-env/test/normalize-options.spec.js b/packages/babel-preset-env/test/normalize-options.spec.js index eefb69e45f46..abe1ba25b9ea 100644 --- a/packages/babel-preset-env/test/normalize-options.spec.js +++ b/packages/babel-preset-env/test/normalize-options.spec.js @@ -84,6 +84,24 @@ describe("normalize-options", () => { }); }); }); + + it("throws when including module plugins", () => { + expect(() => + normalizeOptions.default({ include: ["proposal-dynamic-import"] }), + ).toThrow(); + expect(() => + normalizeOptions.default({ include: ["transform-modules-amd"] }), + ).toThrow(); + }); + + it("allows exclusion of module plugins ", () => { + expect(() => + normalizeOptions.default({ exclude: ["proposal-dynamic-import"] }), + ).not.toThrow(); + expect(() => + normalizeOptions.default({ exclude: ["transform-modules-commonjs"] }), + ).not.toThrow(); + }); }); describe("Config format validation", () => {