From c6afaa74d408a4ce255eba9638b3c01a754280eb Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 16 Dec 2016 17:26:15 -0500 Subject: [PATCH] fix include/exclude for built-ins (#102) --- experimental/babel-preset-env/.gitignore | 1 + experimental/babel-preset-env/README.md | 6 ++--- experimental/babel-preset-env/src/index.js | 26 ++++++++++++++----- .../src/transform-polyfill-require-plugin.js | 10 ++----- .../filters-duplicates/expected.js | 3 --- .../regenerator-false/expected.js | 3 --- .../regenerator-true/expected.js | 3 --- .../exclude-built-ins/actual.js | 1 + .../exclude-built-ins/expected.js | 0 .../exclude-built-ins/options.json | 18 +++++++++++++ .../preset-options/exclude-include/actual.js | 7 +++++ .../exclude-include/expected.js | 12 +++++++++ .../exclude-include/options.json | 20 ++++++++++++++ .../include-built-ins/actual.js | 1 + .../include-built-ins/expected.js | 7 +++++ .../include-built-ins/options.json | 15 +++++++++++ experimental/babel-preset-env/test/index.js | 26 ++++++++++++++----- 17 files changed, 126 insertions(+), 33 deletions(-) create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/actual.js create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/expected.js create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/options.json create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/actual.js create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/expected.js create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/options.json create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/actual.js create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/expected.js create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/options.json diff --git a/experimental/babel-preset-env/.gitignore b/experimental/babel-preset-env/.gitignore index 2d8091eae9..798a62e8f2 100644 --- a/experimental/babel-preset-env/.gitignore +++ b/experimental/babel-preset-env/.gitignore @@ -2,3 +2,4 @@ node_modules lib .DS_Store *.log +.vscode \ No newline at end of file diff --git a/experimental/babel-preset-env/README.md b/experimental/babel-preset-env/README.md index 9e23fd7c26..fe4910ecfa 100644 --- a/experimental/babel-preset-env/README.md +++ b/experimental/babel-preset-env/README.md @@ -144,8 +144,6 @@ An array of plugins to always include. Valid options include any of the [babel plugins](https://github.com/babel/babel-preset-env/blob/master/data/plugin-features.js) or [built-ins](https://github.com/babel/babel-preset-env/blob/master/data/built-in-features.js), such as `transform-es2015-arrow-functions`, `map`, `set`, or `object.assign`. -> For the built-ins like `es6.typed.data-view` just put `typed.data-view`. - This option is useful if there is a bug in a native implementation, or a combination of a non-supported feature + a supported one doesn't work. For example, Node 4 supports native classes but not spread. If `super` is used with a spread argument, then the `transform-es2015-classes` transform needs to be `include`d, as it is not possible to transpile a spread with `super` otherwise. @@ -311,8 +309,8 @@ syntax-trailing-function-commas {} "targets": { "browsers": ["last 2 versions", "safari >= 7"] }, - "include": ["transform-es2015-arrow-functions"], - "exclude": ["transform-regenerator"] + "include": ["transform-es2015-arrow-functions", "es6.map"], + "exclude": ["transform-regenerator", "es6.set"] }] ] } diff --git a/experimental/babel-preset-env/src/index.js b/experimental/babel-preset-env/src/index.js index 422de41ffb..fe6d3d0a9b 100644 --- a/experimental/babel-preset-env/src/index.js +++ b/experimental/babel-preset-env/src/index.js @@ -12,10 +12,17 @@ export const MODULE_TRANSFORMATIONS = { "umd": "transform-es2015-modules-umd" }; +const defaultInclude = [ + "web.timers", + "web.immediate", + "web.dom.iterable" +]; + export const validIncludesAndExcludes = [ ...Object.keys(pluginFeatures), ...Object.keys(MODULE_TRANSFORMATIONS).map((m) => MODULE_TRANSFORMATIONS[m]), - ...Object.keys(builtInsList).slice(4) // remove the `es6.` + ...Object.keys(builtInsList), + ...defaultInclude ]; /** @@ -180,7 +187,11 @@ export function validatePluginsOption(opts = [], type) { Check data/[plugin-features|built-in-features].js in babel-preset-env`); } - return opts; + return { + all: opts, + plugins: opts.filter((opt) => !opt.match(/^(es\d+|web)\./)), + builtIns: opts.filter((opt) => opt.match(/^(es\d+|web)\./)) + }; } const validateIncludeOption = (opts) => validatePluginsOption(opts, "include"); @@ -225,7 +236,7 @@ export default function buildPreset(context, opts = {}) { } const include = validateIncludeOption(opts.whitelist || opts.include); const exclude = validateExcludeOption(opts.exclude); - checkDuplicateIncludeExcludes(include, exclude); + checkDuplicateIncludeExcludes(include.all, exclude.all); const targets = getTargets(opts.targets); const debug = opts.debug; const useBuiltIns = opts.useBuiltIns; @@ -236,7 +247,10 @@ export default function buildPreset(context, opts = {}) { let polyfills; if (useBuiltIns) { polyfills = Object.keys(builtInsList) - .filter((builtInName) => isPluginRequired(targets, builtInsList[builtInName])); + .filter((builtInName) => isPluginRequired(targets, builtInsList[builtInName])) + .concat(defaultInclude) + .filter((plugin) => exclude.builtIns.indexOf(plugin) === -1) + .concat(include.builtIns); } if (debug && !hasBeenLogged) { @@ -260,8 +274,8 @@ export default function buildPreset(context, opts = {}) { } const allTransformations = transformations - .filter((plugin) => exclude.indexOf(plugin) === -1) - .concat(include); + .filter((plugin) => exclude.plugins.indexOf(plugin) === -1) + .concat(include.plugins); const regenerator = allTransformations.indexOf("transform-regenerator") >= 0; const modulePlugin = moduleType !== false && MODULE_TRANSFORMATIONS[moduleType]; diff --git a/experimental/babel-preset-env/src/transform-polyfill-require-plugin.js b/experimental/babel-preset-env/src/transform-polyfill-require-plugin.js index 201543129d..f0da6205f0 100644 --- a/experimental/babel-preset-env/src/transform-polyfill-require-plugin.js +++ b/experimental/babel-preset-env/src/transform-polyfill-require-plugin.js @@ -2,12 +2,6 @@ function isPolyfillSource(value) { return value === "babel-polyfill" || value === "core-js"; } -const alwaysInclude = [ - "web.timers", - "web.immediate", - "web.dom.iterable" -]; - export default function ({ types: t }) { function createImportDeclaration(polyfill) { let declar = t.importDeclaration([], t.stringLiteral(polyfill)); @@ -70,7 +64,7 @@ export default function ({ types: t }) { } path.replaceWithMultiple( - createImports([...state.opts.polyfills, ...alwaysInclude], "import", state.opts.regenerator) + createImports(state.opts.polyfills, "import", state.opts.regenerator) ); } }, @@ -91,7 +85,7 @@ to the "transform-polyfill-require" plugin } bodyPath.replaceWithMultiple( - createImports([...state.opts.polyfills, ...alwaysInclude], "require", state.opts.regenerator) + createImports(state.opts.polyfills, "require", state.opts.regenerator) ); } }); diff --git a/experimental/babel-preset-env/test/fixtures/plugin-options/filters-duplicates/expected.js b/experimental/babel-preset-env/test/fixtures/plugin-options/filters-duplicates/expected.js index 81d166d7ff..6a01cbb4c3 100644 --- a/experimental/babel-preset-env/test/fixtures/plugin-options/filters-duplicates/expected.js +++ b/experimental/babel-preset-env/test/fixtures/plugin-options/filters-duplicates/expected.js @@ -1,5 +1,2 @@ import "core-js/modules/es6.typed.data-view"; import "core-js/modules/es6.reflect.apply"; -import "core-js/modules/web.timers"; -import "core-js/modules/web.immediate"; -import "core-js/modules/web.dom.iterable"; diff --git a/experimental/babel-preset-env/test/fixtures/plugin-options/regenerator-false/expected.js b/experimental/babel-preset-env/test/fixtures/plugin-options/regenerator-false/expected.js index 949a0f6afe..e69de29bb2 100644 --- a/experimental/babel-preset-env/test/fixtures/plugin-options/regenerator-false/expected.js +++ b/experimental/babel-preset-env/test/fixtures/plugin-options/regenerator-false/expected.js @@ -1,3 +0,0 @@ -import "core-js/modules/web.timers"; -import "core-js/modules/web.immediate"; -import "core-js/modules/web.dom.iterable"; \ No newline at end of file diff --git a/experimental/babel-preset-env/test/fixtures/plugin-options/regenerator-true/expected.js b/experimental/babel-preset-env/test/fixtures/plugin-options/regenerator-true/expected.js index 2936f42f1d..50dec607ef 100644 --- a/experimental/babel-preset-env/test/fixtures/plugin-options/regenerator-true/expected.js +++ b/experimental/babel-preset-env/test/fixtures/plugin-options/regenerator-true/expected.js @@ -1,4 +1 @@ -import "core-js/modules/web.timers"; -import "core-js/modules/web.immediate"; -import "core-js/modules/web.dom.iterable"; import "regenerator-runtime/runtime"; diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/actual.js b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/actual.js new file mode 100644 index 0000000000..15d192df49 --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/actual.js @@ -0,0 +1 @@ +import "babel-polyfill"; \ No newline at end of file diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/expected.js b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/options.json b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/options.json new file mode 100644 index 0000000000..bed44453eb --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/options.json @@ -0,0 +1,18 @@ +{ + "presets": [ + ["../../../../lib", { + "targets": { + "chrome": 55 + }, + "modules": false, + "useBuiltIns": true, + "exclude": [ + "es7.string.pad-start", + "es7.string.pad-end", + "web.timers", + "web.immediate", + "web.dom.iterable" + ] + }] + ] +} \ No newline at end of file diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/actual.js b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/actual.js new file mode 100644 index 0000000000..730d8eb539 --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/actual.js @@ -0,0 +1,7 @@ +import "babel-polyfill"; + +async function a() { + await 1; +} + +(() => {}) \ No newline at end of file diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/expected.js b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/expected.js new file mode 100644 index 0000000000..5d0fe180df --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/expected.js @@ -0,0 +1,12 @@ +import "core-js/modules/es7.string.pad-end"; +import "core-js/modules/web.timers"; +import "core-js/modules/web.immediate"; +import "core-js/modules/web.dom.iterable"; +import "core-js/modules/es6.map"; + + +async function a() { + await 1; +} + +(function () {}); diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/options.json b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/options.json new file mode 100644 index 0000000000..ba0e52da56 --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-include/options.json @@ -0,0 +1,20 @@ +{ + "presets": [ + ["../../../../lib", { + "targets": { + "chrome": 55 + }, + "modules": false, + "useBuiltIns": true, + "exclude": [ + "transform-async-to-generator", + "transform-regenerator", + "es7.string.pad-start" + ], + "include": [ + "transform-es2015-arrow-functions", + "es6.map" + ] + }] + ] +} diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/actual.js b/experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/actual.js new file mode 100644 index 0000000000..15d192df49 --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/actual.js @@ -0,0 +1 @@ +import "babel-polyfill"; \ No newline at end of file diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/expected.js b/experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/expected.js new file mode 100644 index 0000000000..cfa4e9f3c4 --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/expected.js @@ -0,0 +1,7 @@ +import "core-js/modules/es7.string.pad-start"; +import "core-js/modules/es7.string.pad-end"; +import "core-js/modules/web.timers"; +import "core-js/modules/web.immediate"; +import "core-js/modules/web.dom.iterable"; +import "core-js/modules/es6.map"; +import "core-js/modules/es6.set"; diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/options.json b/experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/options.json new file mode 100644 index 0000000000..5d1b06b86b --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/include-built-ins/options.json @@ -0,0 +1,15 @@ +{ + "presets": [ + ["../../../../lib", { + "targets": { + "chrome": 55 + }, + "include": [ + "es6.map", + "es6.set" + ], + "modules": false, + "useBuiltIns": true + }] + ] +} diff --git a/experimental/babel-preset-env/test/index.js b/experimental/babel-preset-env/test/index.js index 17e45c3102..e72908f428 100644 --- a/experimental/babel-preset-env/test/index.js +++ b/experimental/babel-preset-env/test/index.js @@ -8,7 +8,6 @@ const { validateModulesOption, validateLooseOption, validatePluginsOption, - validIncludesAndExcludes, checkDuplicateIncludeExcludes } = babelPresetEnv; @@ -219,14 +218,29 @@ describe("babel-preset-env", () => { }); describe("validatePluginsOption", function() { - it("should return an empty array if undefined", function() { - assert.deepEqual(validatePluginsOption(), []); + it("should return empty arrays if undefined", function() { + assert.deepEqual(validatePluginsOption(), { all: [], plugins: [], builtIns: [] }); }); - it("should return itself if in features", function() { + it("should return in transforms array", function() { assert.deepEqual( - validatePluginsOption(validIncludesAndExcludes), - validIncludesAndExcludes + validatePluginsOption(["transform-es2015-arrow-functions"]), + { + all: ["transform-es2015-arrow-functions"], + plugins: ["transform-es2015-arrow-functions"], + builtIns: [] + } + ); + }); + + it("should return in built-ins array", function() { + assert.deepEqual( + validatePluginsOption(["es6.map"]), + { + all: ["es6.map"], + plugins: [], + builtIns: ["es6.map"] + } ); });