diff --git a/experimental/babel-preset-env/README.md b/experimental/babel-preset-env/README.md index fff55c9b3d..a3c8ffda02 100644 --- a/experimental/babel-preset-env/README.md +++ b/experimental/babel-preset-env/README.md @@ -59,6 +59,8 @@ Currently: "chrome, edge, firefox, safari, ie, node". * `modules` - Enable transformation of ES6 module syntax to another module type (Enabled by default to `"commonjs"`). * Can be `false` to not transform modules, or one of `["amd", "umd", "systemjs", "commonjs"]`. * `debug` (boolean) - `console.log` out the targets and plugins being used as well as the version specified in `/data/plugins.json`. +* `whitelist` (Array) - Enable a whitelist of plugins to always include. (Defaults to `[]`) + * Useful if there is a bug in a native implementation, or a combination of a non-supported feature + a supported one doesn't work. (Ex: Node 4 supports native classes but not spread) ```js { @@ -168,6 +170,30 @@ transform-async-to-generator {} syntax-trailing-function-commas {} ``` +### Example with `whitelist` + +```js +// target chrome 52 with whitelist on arrow functions +{ + "presets": [ + ["env", { + "targets": { + "chrome": 52 + }, + "whitelist": ["transform-es2015-arrow-functions"] + }] + ] +} + +Using plugins: + +transform-exponentiation-operator {} +transform-async-to-generator {} +syntax-trailing-function-commas {} +transform-es2015-arrow-functions {} +``` + + ## Caveats ### Using `babel-plugin-transform-object-rest-spread` and targeting node.js 6.5 or higher @@ -176,4 +202,21 @@ You may get a `SyntaxError: Unexpected token ...` error if using the [object-res This is a known issue at [babel/babel#4074](https://github.com/babel/babel/issues/4074). -A simple workaround would be to re-enable the following plugins: `babel-plugin-transform-es2015-destructuring` and `babel-plugin-transform-es2015-parameters`. +A simple workaround would be to re-enable the following plugins: `babel-plugin-transform-es2015-destructuring` and `babel-plugin-transform-es2015-parameters`, which can be done with the `whitelist` option. + +```js +{ + "presets": [ + ["env", { + "targets": { + "node": 6.5 + }, + "whitelist": [ + "transform-es2015-destructuring", + "transform-es2015-parameters" + ] + }] + ], + "plugins": ["transform-object-rest-spread"] +} +``` diff --git a/experimental/babel-preset-env/scripts/build-data.js b/experimental/babel-preset-env/scripts/build-data.js index 759be04827..7433238859 100644 --- a/experimental/babel-preset-env/scripts/build-data.js +++ b/experimental/babel-preset-env/scripts/build-data.js @@ -74,7 +74,7 @@ const getLowestImplementedVersion = ({ features }, env) => { .map(({ res: test, name }, i) => { return Object.keys(test) .filter((t) => t.startsWith(env)) - // TODO: make flagged/etc an options + // Babel assumes strict mode .filter((test) => tests[i].res[test] === true || tests[i].res[test] === "strict") // normalize some keys .map((test) => envMap[test] || test) diff --git a/experimental/babel-preset-env/src/index.js b/experimental/babel-preset-env/src/index.js index 81aa33c12d..7028ed720d 100644 --- a/experimental/babel-preset-env/src/index.js +++ b/experimental/babel-preset-env/src/index.js @@ -93,6 +93,26 @@ export const validateModulesOption = (modulesOpt = "commonjs") => { return modulesOpt; }; +export const validateWhitelistOption = (whitelistOpt = []) => { + if (!Array.isArray(whitelistOpt)) { + throw new Error(`The 'whitelist' option must be an Array of plugins + { + "presets": [ + ["env", { + "targets": { + "chrome": 50 + }, + "whitelist": ["transform-es2015-arrow-functions"] + }] + ] + } + was passed "${whitelistOpt}" instead + `); + } + + return whitelistOpt; +}; + export default function buildPreset(context, opts) { if (!opts.targets) { throw new Error( @@ -112,6 +132,7 @@ babel-preset-env requires a "targets" option: const loose = validateLooseOption(opts.loose); const moduleType = validateModulesOption(opts.modules); + const whitelist = validateWhitelistOption(opts.whitelist); const targets = getTargets(opts.targets); const debug = opts.debug; @@ -136,7 +157,7 @@ babel-preset-env requires a "targets" option: }); } - transformations = transformations.map(pluginName => { + transformations = [...transformations, ...whitelist].map(pluginName => { return [require(`babel-plugin-${pluginName}`), { loose }]; }); diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/whitelist/actual.js b/experimental/babel-preset-env/test/fixtures/preset-options/whitelist/actual.js new file mode 100644 index 0000000000..f6fb17cdfa --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/whitelist/actual.js @@ -0,0 +1 @@ +import a from 'a'; diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/whitelist/expected.js b/experimental/babel-preset-env/test/fixtures/preset-options/whitelist/expected.js new file mode 100644 index 0000000000..64d01c5b22 --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/whitelist/expected.js @@ -0,0 +1,7 @@ +'use strict'; + +var _a = require('a'); + +var _a2 = _interopRequireDefault(_a); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } \ No newline at end of file diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/whitelist/options.json b/experimental/babel-preset-env/test/fixtures/preset-options/whitelist/options.json new file mode 100644 index 0000000000..b36882f25b --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/whitelist/options.json @@ -0,0 +1,9 @@ +{ + "presets": [ + ["../../../../lib", { + "targets": {}, + "whitelist": ["transform-es2015-modules-commonjs"], + "modules": false + }] + ] +}