Add preset-env target esmodules (#7212)
This commit is contained in:
parent
dccfed3601
commit
b3969d35fa
@ -30,6 +30,22 @@ This example only includes the polyfills and code transforms needed for the last
|
||||
}
|
||||
```
|
||||
|
||||
You may also target browsers supporting ES Modules (https://www.ecma-international.org/ecma-262/6.0/#sec-modules). When specifying this option, the browsers field will be ignored. You can use this approach in combination with `<script type="module"></script>` to conditionally serve smaller scripts to users (https://jakearchibald.com/2017/es-modules-in-browsers/#nomodule-for-backwards-compatibility).
|
||||
|
||||
*Please note*: when specifying the esmodules target, browsers targets will be ignored.
|
||||
|
||||
```json
|
||||
{
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
"targets": {
|
||||
"esmodules": true
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Similarly, if you're targeting Node.js instead of the browser, you can configure @babel/preset-env to only include the polyfills and transforms necessary for a particular version:
|
||||
|
||||
```json
|
||||
|
||||
8
packages/babel-preset-env/data/built-in-modules.json
Normal file
8
packages/babel-preset-env/data/built-in-modules.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"es6.module": {
|
||||
"edge": "16",
|
||||
"chrome": "61",
|
||||
"safari": "10.1",
|
||||
"ios_saf": "10.3"
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,7 @@
|
||||
"repository": "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"build-data": "node ./scripts/build-data.js"
|
||||
"build-data": "node ./scripts/build-data.js; node ./scripts/build-modules-support.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-check-constants": "7.0.0-beta.38",
|
||||
@ -59,6 +59,7 @@
|
||||
"@babel/helper-fixtures": "7.0.0-beta.38",
|
||||
"@babel/helper-plugin-test-runner": "7.0.0-beta.38",
|
||||
"compat-table": "kangax/compat-table#3e30cd67a5d3d853caf8424d00ca66d100674d4f",
|
||||
"request": "^2.83.0",
|
||||
"electron-to-chromium": "^1.3.27"
|
||||
}
|
||||
}
|
||||
|
||||
70
packages/babel-preset-env/scripts/build-modules-support.js
Normal file
70
packages/babel-preset-env/scripts/build-modules-support.js
Normal file
@ -0,0 +1,70 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const request = require("request");
|
||||
|
||||
// This mapping represents browsers who have shipped ES Modules Support.
|
||||
// For more information, checkout the specifications:
|
||||
// * https://www.ecma-international.org/ecma-262/6.0/#sec-modules
|
||||
// * https://html.spec.whatwg.org/multipage/scripting.html#attr-script-type
|
||||
const lastKnown = {
|
||||
chrome: 61,
|
||||
firefox: 59,
|
||||
safari: 10.1,
|
||||
ios_saf: 10.3,
|
||||
edge: 16,
|
||||
};
|
||||
|
||||
function input() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
request(
|
||||
"https://raw.githubusercontent.com/Fyrd/caniuse/master/features-json/es6-module.json",
|
||||
function(error, response, body) {
|
||||
if (error || response.statusCode !== 200) {
|
||||
return reject(
|
||||
new Error(
|
||||
`Error retrieving es6-module.json. ${
|
||||
error ? error : `statusCode=${response.statusCode}`
|
||||
}`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const { stats } = JSON.parse(body);
|
||||
const allowedBrowsers = {};
|
||||
|
||||
Object.keys(stats).forEach(browser => {
|
||||
if (browser !== "and_chr") {
|
||||
const browserVersions = stats[browser];
|
||||
const allowedVersions = Object.keys(browserVersions)
|
||||
.filter(value => {
|
||||
return browserVersions[value] === "y";
|
||||
})
|
||||
.sort((a, b) => a - b);
|
||||
|
||||
if (allowedVersions[0] !== undefined) {
|
||||
allowedBrowsers[browser] = allowedVersions[0];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
resolve(allowedBrowsers);
|
||||
} catch (error) {
|
||||
return reject(new Error(`Error parsing es6-module.json.`));
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function output(minVersions) {
|
||||
const dataPath = path.join(__dirname, "../data/built-in-modules.json");
|
||||
const data = {
|
||||
"es6.module": minVersions,
|
||||
};
|
||||
fs.writeFileSync(dataPath, `${JSON.stringify(data, null, 2)}\n`);
|
||||
}
|
||||
|
||||
Promise.resolve(input())
|
||||
.then(minVersions => output(minVersions))
|
||||
.catch(output(lastKnown));
|
||||
@ -183,6 +183,17 @@ export default function buildPreset(
|
||||
console.log("");
|
||||
}
|
||||
|
||||
if (optionsTargets && optionsTargets.esmodules && optionsTargets.browsers) {
|
||||
console.log("");
|
||||
console.log(
|
||||
"@babel/preset-env: esmodules and browsers targets have been specified together.",
|
||||
);
|
||||
console.log(
|
||||
`\`browsers\` target, \`${optionsTargets.browsers}\` will be ignored.`,
|
||||
);
|
||||
console.log("");
|
||||
}
|
||||
|
||||
const targets = getTargets(optionsTargets, {
|
||||
ignoreBrowserslistConfig,
|
||||
configPath,
|
||||
|
||||
@ -4,6 +4,7 @@ import browserslist from "browserslist";
|
||||
import semver from "semver";
|
||||
import { semverify, isUnreleasedVersion, getLowestUnreleased } from "./utils";
|
||||
import { objectToBrowserslist } from "./normalize-options";
|
||||
import browserModulesData from "../data/built-in-modules.json";
|
||||
import type { Targets } from "./types";
|
||||
|
||||
const browserNameMap = {
|
||||
@ -109,6 +110,15 @@ type ParsedResult = {
|
||||
};
|
||||
const getTargets = (targets: Object = {}, options: Object = {}): Targets => {
|
||||
const targetOpts: Targets = {};
|
||||
|
||||
// `esmodules` as a target indicates the specific set of browsers supporting ES Modules.
|
||||
// These values OVERRIDE the `browsers` field.
|
||||
if (targets.esmodules) {
|
||||
const supportsESModules = browserModulesData["es6.module"];
|
||||
targets.browsers = Object.keys(supportsESModules)
|
||||
.map(browser => `${browser} ${supportsESModules[browser]}`)
|
||||
.join(", ");
|
||||
}
|
||||
// Parse browsers target via browserslist;
|
||||
const queryIsValid = isBrowsersQueryValid(targets.browsers);
|
||||
const browsersquery = queryIsValid ? targets.browsers : null;
|
||||
@ -121,6 +131,7 @@ const getTargets = (targets: Object = {}, options: Object = {}): Targets => {
|
||||
}
|
||||
// Parse remaining targets
|
||||
const parsed = Object.keys(targets)
|
||||
.filter(value => value !== "esmodules")
|
||||
.sort()
|
||||
.reduce(
|
||||
(results: ParsedResult, target: string): ParsedResult => {
|
||||
|
||||
@ -78,6 +78,70 @@ describe("getTargets", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("esmodules", () => {
|
||||
it("returns browsers supporting modules", () => {
|
||||
assert.deepEqual(
|
||||
getTargets({
|
||||
esmodules: true,
|
||||
}),
|
||||
{
|
||||
chrome: "61.0.0",
|
||||
safari: "10.1.0",
|
||||
ios: "10.3.0",
|
||||
edge: "16.0.0",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("returns browsers supporting modules, ignoring browsers key", () => {
|
||||
assert.deepEqual(
|
||||
getTargets({
|
||||
esmodules: true,
|
||||
browsers: "ie 8",
|
||||
}),
|
||||
{
|
||||
chrome: "61.0.0",
|
||||
safari: "10.1.0",
|
||||
ios: "10.3.0",
|
||||
edge: "16.0.0",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("returns browser supporting modules and keyed browser overrides", () => {
|
||||
assert.deepEqual(
|
||||
getTargets({
|
||||
esmodules: true,
|
||||
ie: 11,
|
||||
}),
|
||||
{
|
||||
chrome: "61.0.0",
|
||||
safari: "10.1.0",
|
||||
ios: "10.3.0",
|
||||
ie: "11.0.0",
|
||||
edge: "16.0.0",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("returns browser supporting modules and keyed browser overrides, ignoring browsers field", () => {
|
||||
assert.deepEqual(
|
||||
getTargets({
|
||||
esmodules: true,
|
||||
browsers: "ie 10",
|
||||
ie: 11,
|
||||
}),
|
||||
{
|
||||
chrome: "61.0.0",
|
||||
safari: "10.1.0",
|
||||
ios: "10.3.0",
|
||||
ie: "11.0.0",
|
||||
edge: "16.0.0",
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("node", () => {
|
||||
it("should return the current node version with option 'current'", () => {
|
||||
assert.deepEqual(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user