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:
|
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
|
```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",
|
"repository": "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build-data": "node ./scripts/build-data.js"
|
"build-data": "node ./scripts/build-data.js; node ./scripts/build-modules-support.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/plugin-check-constants": "7.0.0-beta.38",
|
"@babel/plugin-check-constants": "7.0.0-beta.38",
|
||||||
@ -59,6 +59,7 @@
|
|||||||
"@babel/helper-fixtures": "7.0.0-beta.38",
|
"@babel/helper-fixtures": "7.0.0-beta.38",
|
||||||
"@babel/helper-plugin-test-runner": "7.0.0-beta.38",
|
"@babel/helper-plugin-test-runner": "7.0.0-beta.38",
|
||||||
"compat-table": "kangax/compat-table#3e30cd67a5d3d853caf8424d00ca66d100674d4f",
|
"compat-table": "kangax/compat-table#3e30cd67a5d3d853caf8424d00ca66d100674d4f",
|
||||||
|
"request": "^2.83.0",
|
||||||
"electron-to-chromium": "^1.3.27"
|
"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("");
|
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, {
|
const targets = getTargets(optionsTargets, {
|
||||||
ignoreBrowserslistConfig,
|
ignoreBrowserslistConfig,
|
||||||
configPath,
|
configPath,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import browserslist from "browserslist";
|
|||||||
import semver from "semver";
|
import semver from "semver";
|
||||||
import { semverify, isUnreleasedVersion, getLowestUnreleased } from "./utils";
|
import { semverify, isUnreleasedVersion, getLowestUnreleased } from "./utils";
|
||||||
import { objectToBrowserslist } from "./normalize-options";
|
import { objectToBrowserslist } from "./normalize-options";
|
||||||
|
import browserModulesData from "../data/built-in-modules.json";
|
||||||
import type { Targets } from "./types";
|
import type { Targets } from "./types";
|
||||||
|
|
||||||
const browserNameMap = {
|
const browserNameMap = {
|
||||||
@ -109,6 +110,15 @@ type ParsedResult = {
|
|||||||
};
|
};
|
||||||
const getTargets = (targets: Object = {}, options: Object = {}): Targets => {
|
const getTargets = (targets: Object = {}, options: Object = {}): Targets => {
|
||||||
const targetOpts: 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;
|
// Parse browsers target via browserslist;
|
||||||
const queryIsValid = isBrowsersQueryValid(targets.browsers);
|
const queryIsValid = isBrowsersQueryValid(targets.browsers);
|
||||||
const browsersquery = queryIsValid ? targets.browsers : null;
|
const browsersquery = queryIsValid ? targets.browsers : null;
|
||||||
@ -121,6 +131,7 @@ const getTargets = (targets: Object = {}, options: Object = {}): Targets => {
|
|||||||
}
|
}
|
||||||
// Parse remaining targets
|
// Parse remaining targets
|
||||||
const parsed = Object.keys(targets)
|
const parsed = Object.keys(targets)
|
||||||
|
.filter(value => value !== "esmodules")
|
||||||
.sort()
|
.sort()
|
||||||
.reduce(
|
.reduce(
|
||||||
(results: ParsedResult, target: string): ParsedResult => {
|
(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", () => {
|
describe("node", () => {
|
||||||
it("should return the current node version with option 'current'", () => {
|
it("should return the current node version with option 'current'", () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user