Add forceAllTransforms option and deprecate Uglify target (#264)

This commit is contained in:
Brian Ng 2017-04-26 14:11:53 -05:00 committed by GitHub
parent ccc31f7878
commit aad13388c7
12 changed files with 209 additions and 96 deletions

View File

@ -120,16 +120,6 @@ A query to select browsers (ex: last 2 versions, > 5%) using [browserslist](http
Note, browsers' results are overridden by explicit items from `targets`.
### `targets.uglify`
`number | true`
UglifyJS does not currently support any ES6 syntax, so if you are using Uglify to minify your code, targeting later browsers may cause Uglify to throw syntax errors.
To prevent these errors - specify the uglify option, which will enable all plugins and, as a result, fully compile your code to ES5. However, the `useBuiltIns` option will still work as before, and only include the polyfills that your target(s) need.
> 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`.
@ -259,6 +249,47 @@ import "babel-polyfill/core-js/modules/es7.string.pad-end";
Don't add polyfills automatically per file, or transform `import "babel-polyfill"` to individual polyfills.
### `forceAllTransforms`
`boolean`, defaults to `false`.
<p><details>
<summary><b>Example</b></summary>
With Babel 7's .babelrc.js support, you can force all transforms to be run if env is set to `production`.
```js
module.exports = {
presets: [
["env", {
targets: {
chrome: 59,
edge: 13,
firefox: 50,
},
// for uglifyjs...
forceAllTransforms: process.env === "production"
}],
],
};
```
</details></p>
> NOTE: `targets.uglify` is deprecated and will be removed in the next major in
favor of this.
By default, this preset will run all the transforms needed for the targeted
environment(s). Enable this option if you want to force running _all_
transforms, which is useful if the output will be run through UglifyJS or an
environment that only supports ES5.
> 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).
---
## Examples

View File

@ -107,18 +107,42 @@ const filterItems = (list, includes, excludes, targets, defaultItems) => {
};
export default function buildPreset(context, opts = {}) {
const validatedOptions = normalizeOptions(opts);
const { debug, loose, moduleType, spec, useBuiltIns } = validatedOptions;
const {
debug,
exclude: optionsExclude,
forceAllTransforms,
include: optionsInclude,
loose,
moduleType,
spec,
targets: optionsTargets,
useBuiltIns,
} = normalizeOptions(opts);
const targets = getTargets(validatedOptions.targets);
const include = transformIncludesAndExcludes(validatedOptions.include);
const exclude = transformIncludesAndExcludes(validatedOptions.exclude);
// TODO: remove this in next major
let hasUglifyTarget = false;
if (optionsTargets && 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("");
}
const targets = getTargets(optionsTargets);
const include = transformIncludesAndExcludes(optionsInclude);
const exclude = transformIncludesAndExcludes(optionsExclude);
const transformTargets = forceAllTransforms || hasUglifyTarget ? {} : targets;
const transformations = filterItems(
pluginList,
include.plugins,
exclude.plugins,
targets,
transformTargets,
);
let polyfills;

View File

@ -57,9 +57,13 @@ export const validateBoolOption = (name, value, defaultValue) => {
export const validateLooseOption = looseOpt =>
validateBoolOption("loose", looseOpt, false);
export const validateSpecOption = specOpt =>
validateBoolOption("spec", specOpt, false);
export const validateForceAllTransformsOption = forceAllTransforms =>
validateBoolOption("forceAllTransforms", forceAllTransforms, false);
export const validateModulesOption = (modulesOpt = "commonjs") => {
invariant(
modulesOpt === false ||
@ -97,6 +101,9 @@ export default function normalizeOptions(opts) {
return {
debug: opts.debug,
exclude: validateIncludesAndExcludes(opts.exclude, "exclude"),
forceAllTransforms: validateForceAllTransformsOption(
opts.forceAllTransforms,
),
include: validateIncludesAndExcludes(opts.include, "include"),
loose: validateLooseOption(opts.loose),
moduleType: validateModulesOption(opts.modules),

View File

@ -26,30 +26,27 @@ const semverMin = (first: ?string, second: string): string => {
};
const getLowestVersions = browsers => {
return browsers.reduce(
(all, browser) => {
const [browserName, browserVersion] = browser.split(" ");
const normalizedBrowserName = browserNameMap[browserName];
if (!normalizedBrowserName) {
return all;
}
try {
// Browser version can return as "10.0-10.2"
const splitVersion = browserVersion.split("-")[0];
const parsedBrowserVersion = semverify(splitVersion);
all[normalizedBrowserName] = semverMin(
all[normalizedBrowserName],
parsedBrowserVersion,
);
} catch (e) {}
return browsers.reduce((all, browser) => {
const [browserName, browserVersion] = browser.split(" ");
const normalizedBrowserName = browserNameMap[browserName];
if (!normalizedBrowserName) {
return all;
},
{},
);
}
try {
// Browser version can return as "10.0-10.2"
const splitVersion = browserVersion.split("-")[0];
const parsedBrowserVersion = semverify(splitVersion);
all[normalizedBrowserName] = semverMin(
all[normalizedBrowserName],
parsedBrowserVersion,
);
} catch (e) {}
return all;
}, {});
};
const outputDecimalWarning = (decimalTargets: Array<Object>): void => {
@ -60,7 +57,8 @@ const outputDecimalWarning = (decimalTargets: Array<Object>): void => {
console.log("Warning, the following targets are using a decimal version:");
console.log("");
decimalTargets.forEach(({ target, value }) =>
console.log(` ${target}: ${value}`));
console.log(` ${target}: ${value}`),
);
console.log("");
console.log(
"We recommend using a string for minor/patch versions to avoid numbers like 6.10",
@ -81,6 +79,7 @@ const targetParserMap = {
return [target, parsed];
},
// TODO: Remove in next version.
// Only valid value for Uglify is `true`
uglify: (target, value) => [target, value === true],
};

View File

@ -1,37 +1,39 @@
The uglify target has been deprecated. Set the top level
option `forceAllTransforms: true` instead.
babel-preset-env: `DEBUG` option
Using targets:
{
"chrome": "55",
"uglify": true
"chrome": "55"
}
Modules transform: false
Using plugins:
check-es2015-constants {"uglify":true}
transform-es2015-arrow-functions {"uglify":true}
transform-es2015-block-scoped-functions {"uglify":true}
transform-es2015-block-scoping {"uglify":true}
transform-es2015-classes {"uglify":true}
transform-es2015-computed-properties {"uglify":true}
transform-es2015-destructuring {"uglify":true}
transform-es2015-duplicate-keys {"uglify":true}
transform-es2015-for-of {"uglify":true}
transform-es2015-function-name {"uglify":true}
transform-es2015-literals {"uglify":true}
transform-es2015-object-super {"uglify":true}
transform-es2015-parameters {"uglify":true}
transform-es2015-shorthand-properties {"uglify":true}
transform-es2015-spread {"uglify":true}
transform-es2015-sticky-regex {"uglify":true}
transform-es2015-template-literals {"uglify":true}
transform-es2015-typeof-symbol {"uglify":true}
transform-es2015-unicode-regex {"uglify":true}
transform-regenerator {"uglify":true}
transform-exponentiation-operator {"uglify":true}
transform-async-to-generator {"uglify":true}
syntax-trailing-function-commas {"chrome":"55","uglify":true}
check-es2015-constants {}
transform-es2015-arrow-functions {}
transform-es2015-block-scoped-functions {}
transform-es2015-block-scoping {}
transform-es2015-classes {}
transform-es2015-computed-properties {}
transform-es2015-destructuring {}
transform-es2015-duplicate-keys {}
transform-es2015-for-of {}
transform-es2015-function-name {}
transform-es2015-literals {}
transform-es2015-object-super {}
transform-es2015-parameters {}
transform-es2015-shorthand-properties {}
transform-es2015-spread {}
transform-es2015-sticky-regex {}
transform-es2015-template-literals {}
transform-es2015-typeof-symbol {}
transform-es2015-unicode-regex {}
transform-regenerator {}
transform-exponentiation-operator {}
transform-async-to-generator {}
syntax-trailing-function-commas {"chrome":"55"}
Polyfills
=========

View File

@ -0,0 +1,13 @@
{
"presets": [
["../../lib", {
"debug": true,
"modules": false,
"targets": {
"chrome": 55
},
"useBuiltIns": "entry",
"forceAllTransforms": true
}]
]
}

View File

@ -0,0 +1,44 @@
babel-preset-env: `DEBUG` option
Using targets:
{
"chrome": "55"
}
Modules transform: false
Using plugins:
check-es2015-constants {}
transform-es2015-arrow-functions {}
transform-es2015-block-scoped-functions {}
transform-es2015-block-scoping {}
transform-es2015-classes {}
transform-es2015-computed-properties {}
transform-es2015-destructuring {}
transform-es2015-duplicate-keys {}
transform-es2015-for-of {}
transform-es2015-function-name {}
transform-es2015-literals {}
transform-es2015-object-super {}
transform-es2015-parameters {}
transform-es2015-shorthand-properties {}
transform-es2015-spread {}
transform-es2015-sticky-regex {}
transform-es2015-template-literals {}
transform-es2015-typeof-symbol {}
transform-es2015-unicode-regex {}
transform-regenerator {}
transform-exponentiation-operator {}
transform-async-to-generator {}
syntax-trailing-function-commas {"chrome":"55"}
Polyfills
=========
Replaced `babel-polyfill` with the following polyfills:
es7.string.pad-start {"chrome":"55"}
es7.string.pad-end {"chrome":"55"}
web.timers {"chrome":"55"}
web.immediate {"chrome":"55"}
web.dom.iterable {"chrome":"55"}
src/in.js -> lib/in.js

View File

@ -1,12 +1,12 @@
{
"presets": [
["../../../../lib", {
"targets": {
"chrome": 55,
"uglify": true
},
"modules": false,
"useBuiltIns": "entry"
"targets": {
"chrome": 55
},
"useBuiltIns": "entry",
"forceAllTransforms": true
}]
]
}

View File

@ -6,6 +6,7 @@ const assert = require("assert");
const {
checkDuplicateIncludeExcludes,
normalizePluginNames,
validateForceAllTransformsOption,
validateIncludesAndExcludes,
validateLooseOption,
validateModulesOption,
@ -38,39 +39,31 @@ describe("normalize-options", () => {
});
});
describe("validateLooseOption", () => {
it("`undefined` option returns false", () => {
assert(validateLooseOption() === false);
});
const testBoolOption = validator => {
describe(validator.name, () => {
it("`undefined` option returns false", () => {
assert(validator() === false);
});
it("`false` option returns false", () => {
assert(validateLooseOption(false) === false);
});
it("`false` option returns false", () => {
assert(validator(false) === false);
});
it("`true` option returns true", () => {
assert(validateLooseOption(true) === true);
});
it("`true` option returns true", () => {
assert(validator(true) === true);
});
it("array option is invalid", () => {
assert.throws(() => {
validateLooseOption([]);
it("array option is invalid", () => {
assert.throws(() => {
validateLooseOption([]);
});
});
});
});
};
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);
});
});
testBoolOption(validateLooseOption);
testBoolOption(validateSpecOption);
testBoolOption(validateForceAllTransformsOption);
describe("checkDuplicateIncludeExcludes", function() {
it("should throw if duplicate names in both", function() {