From 75db91940ef9d5c0b1c218410fd8eda39dafcad6 Mon Sep 17 00:00:00 2001 From: Diogo Franco Date: Sat, 15 Apr 2017 00:11:36 +0900 Subject: [PATCH] Support `spec` option (#98) --- experimental/babel-preset-env/README.md | 6 ++++++ experimental/babel-preset-env/src/index.js | 7 ++++--- .../babel-preset-env/src/normalize-options.js | 19 +++++++++++++------ .../fixtures/preset-options/spec/actual.js | 2 ++ .../fixtures/preset-options/spec/expected.js | 10 ++++++++++ .../fixtures/preset-options/spec/options.json | 7 +++++++ .../test/normalize-options.spec.js | 17 ++++++++++++++++- 7 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/spec/actual.js create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/spec/expected.js create mode 100644 experimental/babel-preset-env/test/fixtures/preset-options/spec/options.json diff --git a/experimental/babel-preset-env/README.md b/experimental/babel-preset-env/README.md index 5884ae151c..b3d9e01f94 100644 --- a/experimental/babel-preset-env/README.md +++ b/experimental/babel-preset-env/README.md @@ -132,6 +132,12 @@ To prevent these errors - specify the uglify option, which will enable all plugi > NOTE: Uglify has a work-in-progress "Harmony" branch to address the lack of ES6 support, but it is not yet stable. You can follow its progress in [UglifyJS2 issue #448](https://github.com/mishoo/UglifyJS2/issues/448). If you require an alternative minifier which _does_ support ES6 syntax, we recommend using [Babili](https://github.com/babel/babili). +### `spec` + +`boolean`, defaults to `false`. + +Enable more spec compliant, but potentially slower, transformations for any plugins in this preset that support them. + ### `loose` `boolean`, defaults to `false`. diff --git a/experimental/babel-preset-env/src/index.js b/experimental/babel-preset-env/src/index.js index c94c222e11..fe68ea2339 100644 --- a/experimental/babel-preset-env/src/index.js +++ b/experimental/babel-preset-env/src/index.js @@ -165,13 +165,12 @@ function getPlatformSpecificDefaultFor(targets) { export default function buildPreset(context, opts = {}) { const validatedOptions = normalizeOptions(opts); - const { debug, loose, moduleType, useBuiltIns } = validatedOptions; + const { debug, loose, moduleType, spec, useBuiltIns } = validatedOptions; const targets = getTargets(validatedOptions.targets); const include = transformIncludesAndExcludes(validatedOptions.include); const exclude = transformIncludesAndExcludes(validatedOptions.exclude); - const filterPlugins = filterItem.bind(null, targets, exclude.plugins, pluginList); const transformations = Object.keys(pluginList) .filter(filterPlugins) @@ -210,11 +209,13 @@ export default function buildPreset(context, opts = {}) { const modulePlugin = moduleType !== false && moduleTransformations[moduleType]; const plugins = []; + // NOTE: not giving spec here yet to avoid compatibility issues when + // babel-plugin-transform-es2015-modules-commonjs gets its spec mode modulePlugin && plugins.push([require(`babel-plugin-${modulePlugin}`), { loose }]); plugins.push(...transformations.map((pluginName) => - [require(`babel-plugin-${pluginName}`), { loose }] + [require(`babel-plugin-${pluginName}`), { spec, loose }] )); useBuiltIns && diff --git a/experimental/babel-preset-env/src/normalize-options.js b/experimental/babel-preset-env/src/normalize-options.js index b57aa48de2..9b8ebd014a 100644 --- a/experimental/babel-preset-env/src/normalize-options.js +++ b/experimental/babel-preset-env/src/normalize-options.js @@ -53,15 +53,21 @@ export const checkDuplicateIncludeExcludes = (include = [], exclude = []) => { ); }; -export const validateLooseOption = (looseOpt = false) => { - invariant( - typeof looseOpt === "boolean", - "Invalid Option: The 'loose' option must be a boolean." - ); +export const validateBoolOption = (name, value, defaultValue) => { + if (typeof value === "undefined") { + value = defaultValue; + } - return looseOpt; + if (typeof value !== "boolean") { + throw new Error(`Preset env: '${name}' option must be a boolean.`); + } + + return value; }; +export const validateLooseOption = (looseOpt) => validateBoolOption("loose", looseOpt, false); +export const validateSpecOption = (specOpt) => validateBoolOption("spec", specOpt, false); + export const validateModulesOption = (modulesOpt = "commonjs") => { invariant( modulesOpt === false || Object.keys(moduleTransformations).indexOf(modulesOpt) > -1, @@ -104,6 +110,7 @@ export default function normalizeOptions(opts) { include: validateIncludesAndExcludes(opts.include, "include"), loose: validateLooseOption(opts.loose), moduleType: validateModulesOption(opts.modules), + spec: validateSpecOption(opts.spec), targets: opts.targets, useBuiltIns: opts.useBuiltIns }; diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/spec/actual.js b/experimental/babel-preset-env/test/fixtures/preset-options/spec/actual.js new file mode 100644 index 0000000000..51403eebdc --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/spec/actual.js @@ -0,0 +1,2 @@ +const bar = "bar"; +const x = () => `foo${bar}`; diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/spec/expected.js b/experimental/babel-preset-env/test/fixtures/preset-options/spec/expected.js new file mode 100644 index 0000000000..67366fe06e --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/spec/expected.js @@ -0,0 +1,10 @@ +"use strict"; + +function _newArrowCheck(innerThis, boundThis) { if (innerThis !== boundThis) { throw new TypeError("Cannot instantiate an arrow function"); } } + +var bar = "bar"; +var x = function () { + _newArrowCheck(undefined, undefined); + + return "foo" + bar; +}.bind(undefined); \ No newline at end of file diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/spec/options.json b/experimental/babel-preset-env/test/fixtures/preset-options/spec/options.json new file mode 100644 index 0000000000..8aefcdc8ed --- /dev/null +++ b/experimental/babel-preset-env/test/fixtures/preset-options/spec/options.json @@ -0,0 +1,7 @@ +{ + "presets": [ + ["../../../../lib", { + "spec": true + }] + ] +} diff --git a/experimental/babel-preset-env/test/normalize-options.spec.js b/experimental/babel-preset-env/test/normalize-options.spec.js index da5632198c..2db9bb388d 100644 --- a/experimental/babel-preset-env/test/normalize-options.spec.js +++ b/experimental/babel-preset-env/test/normalize-options.spec.js @@ -5,10 +5,11 @@ const assert = require("assert"); const { checkDuplicateIncludeExcludes, + normalizePluginNames, validateIncludesAndExcludes, validateLooseOption, validateModulesOption, - normalizePluginNames + validateSpecOption, } = normalizeOptions; describe("normalize-options", () => { @@ -60,6 +61,20 @@ describe("normalize-options", () => { }); }); + describe("validateSpecOption", () => { + it("`undefined` option returns false", () => { + assert(validateSpecOption() === false); + }); + + it("`false` option returns false", () => { + assert(validateSpecOption(false) === false); + }); + + it("`true` option returns true", () => { + assert(validateSpecOption(true) === true); + }); + }); + describe("checkDuplicateIncludeExcludes", function() { it("should throw if duplicate names in both", function() { assert.throws(() => {