From a196b73c6af08948d75af809f9986d6ca891673c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Sat, 17 Oct 2020 00:30:26 +0200 Subject: [PATCH] Add support for top-level targets to `@babel/preset-env` --- packages/babel-preset-env/src/index.js | 90 +++++++++++++------ .../top-level-targets-shadowed/input.mjs | 1 + .../top-level-targets-shadowed/options.json | 8 ++ .../top-level-targets-shadowed/stdout.txt | 26 ++++++ .../debug/top-level-targets/input.mjs | 1 + .../debug/top-level-targets/options.json | 8 ++ .../debug/top-level-targets/stdout.txt | 23 +++++ 7 files changed, 129 insertions(+), 28 deletions(-) create mode 100644 packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/input.mjs create mode 100644 packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/options.json create mode 100644 packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/stdout.txt create mode 100644 packages/babel-preset-env/test/fixtures/debug/top-level-targets/input.mjs create mode 100644 packages/babel-preset-env/test/fixtures/debug/top-level-targets/options.json create mode 100644 packages/babel-preset-env/test/fixtures/debug/top-level-targets/stdout.txt diff --git a/packages/babel-preset-env/src/index.js b/packages/babel-preset-env/src/index.js index e3cfb7a623ce..90f30f626fdb 100644 --- a/packages/babel-preset-env/src/index.js +++ b/packages/babel-preset-env/src/index.js @@ -206,6 +206,45 @@ export const getPolyfillPlugins = ({ return polyfillPlugins; }; +function getLocalTargets( + optionsTargets, + ignoreBrowserslistConfig, + configPath, + browserslistEnv, +) { + // TODO: remove this in next major + let hasUglifyTarget = false; + + if (optionsTargets?.uglify) { + hasUglifyTarget = true; + delete optionsTargets.uglify; + + console.log(""); + console.log("The uglify target has been deprecated. Set the top level"); + console.log("option `forceAllTransforms: true` instead."); + console.log(""); + } + + if (optionsTargets?.esmodules && optionsTargets.browsers) { + console.log(""); + console.log( + "@babel/preset-env: esmodules and browsers targets have been specified together.", + ); + console.log( + // $FlowIgnore + `\`browsers\` target, \`${optionsTargets.browsers}\` will be ignored.`, + ); + console.log(""); + } + + const localTargets = getTargets( + // $FlowIgnore optionsTargets doesn't have an "uglify" property anymore + (optionsTargets: InputTargets), + { ignoreBrowserslistConfig, configPath, browserslistEnv }, + ); + return { hasUglifyTarget, localTargets }; +} + function supportsStaticESM(caller) { return !!caller?.supportsStaticESM; } @@ -225,6 +264,9 @@ function supportsTopLevelAwait(caller) { export default declare((api, opts) => { api.assertVersion(7); + // TODO(Babel 8): api.targets() is always defined, no need to fallback + const babelTargets = api.targets?.() ?? {}; + const { bugfixes, configPath, @@ -242,41 +284,33 @@ export default declare((api, opts) => { corejs: { version: corejs, proposals }, browserslistEnv, } = normalizeOptions(opts); - // TODO: remove this in next major - let hasUglifyTarget = false; - - if (optionsTargets?.uglify) { - hasUglifyTarget = true; - delete optionsTargets.uglify; - console.log(""); - console.log("The uglify target has been deprecated. Set the top level"); - console.log("option `forceAllTransforms: true` instead."); - console.log(""); - } - - if (optionsTargets?.esmodules && optionsTargets.browsers) { - console.log(""); - console.log( - "@babel/preset-env: esmodules and browsers targets have been specified together.", - ); - console.log( - // $FlowIgnore - `\`browsers\` target, \`${optionsTargets.browsers}\` will be ignored.`, + let targets = babelTargets; + let transformTargets = forceAllTransforms ? {} : babelTargets; + + if ( + // If any browserslist-related option is specified, fallback to the old + // behavior of not using the targets specified in the top-level options. + opts.targets || + opts.configPath || + opts.browserslistEnv || + opts.ignoreBrowserslistConfig + ) { + const { hasUglifyTarget, localTargets } = getLocalTargets( + optionsTargets, + ignoreBrowserslistConfig, + configPath, + browserslistEnv, ); - console.log(""); + + targets = localTargets; + if (hasUglifyTarget) transformTargets = {}; + else if (!forceAllTransforms) transformTargets = localTargets; } - const targets = getTargets( - // $FlowIgnore optionsTargets doesn't have an "uglify" property anymore - (optionsTargets: InputTargets), - { ignoreBrowserslistConfig, configPath, browserslistEnv }, - ); const include = transformIncludesAndExcludes(optionsInclude); const exclude = transformIncludesAndExcludes(optionsExclude); - const transformTargets = forceAllTransforms || hasUglifyTarget ? {} : targets; - const compatData = getPluginList(shippedProposals, bugfixes); const shouldSkipExportNamespaceFrom = (modules === "auto" && api.caller?.(supportsExportNamespaceFrom)) || diff --git a/packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/input.mjs b/packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/input.mjs new file mode 100644 index 000000000000..fbb8052d71ab --- /dev/null +++ b/packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/input.mjs @@ -0,0 +1 @@ +foo?.bar; diff --git a/packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/options.json b/packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/options.json new file mode 100644 index 000000000000..bd767ffbae7b --- /dev/null +++ b/packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/options.json @@ -0,0 +1,8 @@ +{ + "validateLogs": true, + "ignoreOutput": true, + "targets": "chrome 80", + "presets": [ + ["env", { "debug": true, "targets": "chrome 60" }] + ] +} diff --git a/packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/stdout.txt b/packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/stdout.txt new file mode 100644 index 000000000000..2548b104e672 --- /dev/null +++ b/packages/babel-preset-env/test/fixtures/debug/top-level-targets-shadowed/stdout.txt @@ -0,0 +1,26 @@ +@babel/preset-env: `DEBUG` option + +Using targets: +{ + "chrome": "60" +} + +Using modules transform: auto + +Using plugins: + proposal-numeric-separator { "chrome":"60" } + proposal-logical-assignment-operators { "chrome":"60" } + proposal-nullish-coalescing-operator { "chrome":"60" } + proposal-optional-chaining { "chrome":"60" } + proposal-json-strings { "chrome":"60" } + proposal-optional-catch-binding { "chrome":"60" } + proposal-async-generator-functions { "chrome":"60" } + syntax-object-rest-spread { "chrome":"60" } + transform-dotall-regex { "chrome":"60" } + proposal-unicode-property-regex { "chrome":"60" } + transform-named-capturing-groups-regex { "chrome":"60" } + proposal-export-namespace-from { "chrome":"60" } + transform-modules-commonjs { "chrome":"60" } + proposal-dynamic-import { "chrome":"60" } + +Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set. diff --git a/packages/babel-preset-env/test/fixtures/debug/top-level-targets/input.mjs b/packages/babel-preset-env/test/fixtures/debug/top-level-targets/input.mjs new file mode 100644 index 000000000000..fbb8052d71ab --- /dev/null +++ b/packages/babel-preset-env/test/fixtures/debug/top-level-targets/input.mjs @@ -0,0 +1 @@ +foo?.bar; diff --git a/packages/babel-preset-env/test/fixtures/debug/top-level-targets/options.json b/packages/babel-preset-env/test/fixtures/debug/top-level-targets/options.json new file mode 100644 index 000000000000..dbc78d327863 --- /dev/null +++ b/packages/babel-preset-env/test/fixtures/debug/top-level-targets/options.json @@ -0,0 +1,8 @@ +{ + "validateLogs": true, + "ignoreOutput": true, + "targets": "chrome 80", + "presets": [ + ["env", { "debug": true }] + ] +} diff --git a/packages/babel-preset-env/test/fixtures/debug/top-level-targets/stdout.txt b/packages/babel-preset-env/test/fixtures/debug/top-level-targets/stdout.txt new file mode 100644 index 000000000000..762aee9a191e --- /dev/null +++ b/packages/babel-preset-env/test/fixtures/debug/top-level-targets/stdout.txt @@ -0,0 +1,23 @@ +@babel/preset-env: `DEBUG` option + +Using targets: +{ + "chrome": "80" +} + +Using modules transform: auto + +Using plugins: + syntax-numeric-separator { "chrome":"80" } + proposal-logical-assignment-operators { "chrome":"80" } + syntax-nullish-coalescing-operator { "chrome":"80" } + syntax-optional-chaining { "chrome":"80" } + syntax-json-strings { "chrome":"80" } + syntax-optional-catch-binding { "chrome":"80" } + syntax-async-generators { "chrome":"80" } + syntax-object-rest-spread { "chrome":"80" } + transform-modules-commonjs { "chrome":"80" } + proposal-dynamic-import { "chrome":"80" } + proposal-export-namespace-from {} + +Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set.