Skip to content
This repository has been archived by the owner on May 11, 2018. It is now read-only.

Commit

Permalink
fix include/exclude for built-ins (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
hzoo committed Dec 16, 2016
1 parent 99bde04 commit a86d5dc
Show file tree
Hide file tree
Showing 17 changed files with 126 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,3 +2,4 @@ node_modules
lib
.DS_Store
*.log
.vscode
6 changes: 2 additions & 4 deletions README.md
Expand Up @@ -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.
Expand Down Expand Up @@ -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"]
}]
]
}
Expand Down
26 changes: 20 additions & 6 deletions src/index.js
Expand Up @@ -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
];

/**
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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];
Expand Down
10 changes: 2 additions & 8 deletions src/transform-polyfill-require-plugin.js
Expand Up @@ -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));
Expand Down Expand Up @@ -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)
);
}
},
Expand All @@ -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)
);
}
});
Expand Down
3 changes: 0 additions & 3 deletions 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";
3 changes: 0 additions & 3 deletions 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";
3 changes: 0 additions & 3 deletions 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";
1 change: 1 addition & 0 deletions test/fixtures/preset-options/exclude-built-ins/actual.js
@@ -0,0 +1 @@
import "babel-polyfill";
Empty file.
18 changes: 18 additions & 0 deletions 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"
]
}]
]
}
7 changes: 7 additions & 0 deletions test/fixtures/preset-options/exclude-include/actual.js
@@ -0,0 +1,7 @@
import "babel-polyfill";

async function a() {
await 1;
}

(() => {})
12 changes: 12 additions & 0 deletions 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 () {});
20 changes: 20 additions & 0 deletions 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"
]
}]
]
}
1 change: 1 addition & 0 deletions test/fixtures/preset-options/include-built-ins/actual.js
@@ -0,0 +1 @@
import "babel-polyfill";
7 changes: 7 additions & 0 deletions 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";
15 changes: 15 additions & 0 deletions 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
}]
]
}
26 changes: 20 additions & 6 deletions test/index.js
Expand Up @@ -8,7 +8,6 @@ const {
validateModulesOption,
validateLooseOption,
validatePluginsOption,
validIncludesAndExcludes,
checkDuplicateIncludeExcludes
} = babelPresetEnv;

Expand Down Expand Up @@ -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"]
}
);
});

Expand Down

0 comments on commit a86d5dc

Please sign in to comment.