Add safari technology preview for babel-preset-env. (#6791)

This commit is contained in:
Artem Yavorsky 2017-11-16 01:14:54 +02:00 committed by Brian Ng
parent 0f2ab2fe20
commit 48906604f2
15 changed files with 152 additions and 15 deletions

View File

@ -181,7 +181,7 @@ For more information on setting options for a preset, refer to the [plugin/prese
Takes an object of environment versions to support.
Each target environment takes a number or a string (we recommend using a string when specifying minor versions like `node: "6.10"`).
Each target environment takes a number or a string (we recommend using a string when specifying minor versions like `node: "6.10"`). You can also specify `tp` (technology preview) version for Safari.
Example environments: `chrome`, `opera`, `edge`, `firefox`, `safari`, `ie`, `ios`, `android`, `node`, `electron`.
@ -197,7 +197,7 @@ If you want to compile against the current node version, you can specify `"node"
`Array<string> | string`
A query to select browsers (ex: last 2 versions, > 5%) using [browserslist](https://github.com/ai/browserslist).
A query to select browsers (ex: last 2 versions, > 5%, safari tp) using [browserslist](https://github.com/ai/browserslist).
Note, browsers' results are overridden by explicit items from `targets`.

View File

@ -948,6 +948,7 @@
},
"es7.promise.finally": {
"chrome": "63",
"safari": "tp",
"opera": "50"
}
}

View File

@ -231,14 +231,18 @@
"proposal-async-generator-functions": {
"chrome": "63",
"firefox": "57",
"safari": "tp",
"opera": "50"
},
"proposal-object-rest-spread": {
"chrome": "60",
"firefox": "55",
"safari": "tp",
"node": "8.3",
"opera": "47"
},
"proposal-optional-catch-binding": {},
"proposal-optional-catch-binding": {
"safari": "tp"
},
"proposal-unicode-property-regex": {}
}

View File

@ -0,0 +1,3 @@
module.exports = {
safari: "tp",
};

View File

@ -7,6 +7,7 @@ const flattenDeep = require("lodash/flattenDeep");
const isEqual = require("lodash/isEqual");
const mapValues = require("lodash/mapValues");
const pickBy = require("lodash/pickBy");
const unreleasedLabels = require("../data/unreleased-labels");
const electronToChromiumVersions = require("electron-to-chromium").versions;
const electronToChromiumKeys = Object.keys(
@ -185,6 +186,7 @@ const getLowestImplementedVersion = ({ features }, env) => {
return result;
}, []);
const unreleasedLabelForEnv = unreleasedLabels[env];
const envTests = tests.map(({ res: test, isBuiltIn }, i) => {
// Babel itself doesn't implement the feature correctly,
// don't count against it
@ -200,9 +202,15 @@ const getLowestImplementedVersion = ({ features }, env) => {
.filter(
test => tests[i].res[test] === true || tests[i].res[test] === "strict"
)
// normalize some keys
.map(test => test.replace("_", "."))
.filter(test => !isNaN(parseFloat(test.replace(env, ""))))
// normalize some keys and get version from full string.
.map(test => {
return test.replace("_", ".").replace(env, "");
})
// version must be label from the unreleasedLabels (like tp) or number.
.filter(
version =>
unreleasedLabelForEnv === version || !isNaN(parseFloat(version))
)
.shift()
);
});
@ -220,9 +228,14 @@ const getLowestImplementedVersion = ({ features }, env) => {
return null;
}
return envTests.map(str => Number(str.replace(env, ""))).reduce((a, b) => {
return a < b ? b : a;
});
return envTests
.map(str => {
const version = str.replace(env, "");
return version === unreleasedLabelForEnv ? version : parseFloat(version);
})
.reduce((a, b) => {
return b === unreleasedLabelForEnv || a < b ? b : a;
});
};
const generateData = (environments, features) => {

View File

@ -16,7 +16,12 @@ import useBuiltInsEntryPlugin from "./use-built-ins-entry-plugin";
import addUsedBuiltInsPlugin from "./use-built-ins-plugin";
import getTargets from "./targets-parser";
import availablePlugins from "./available-plugins";
import { filterStageFromList, prettifyTargets, semverify } from "./utils";
import {
filterStageFromList,
prettifyTargets,
semverify,
isUnreleasedVersion,
} from "./utils";
import type { Plugin, Targets } from "./types";
const getPlugin = (pluginName: string) => {
@ -61,6 +66,13 @@ export const isPluginRequired = (
const lowestImplementedVersion: string = plugin[environment];
const lowestTargetedVersion: string = supportedEnvironments[environment];
// If targets has unreleased value as a lowest version, then don't require a plugin.
if (isUnreleasedVersion(lowestTargetedVersion, environment)) {
return false;
// Include plugin if it is supported in the unreleased environment, which wasn't specified in targets
} else if (isUnreleasedVersion(lowestImplementedVersion, environment)) {
return true;
}
if (!semver.valid(lowestTargetedVersion)) {
throw new Error(

View File

@ -2,7 +2,7 @@
import browserslist from "browserslist";
import semver from "semver";
import { semverify } from "./utils";
import { semverify, isUnreleasedVersion, getLowestUnreleased } from "./utils";
import { objectToBrowserslist } from "./normalize-options";
import type { Targets } from "./types";
@ -20,7 +20,7 @@ const browserNameMap = {
const isBrowsersQueryValid = (browsers: string | Array<string>): boolean =>
typeof browsers === "string" || Array.isArray(browsers);
const semverMin = (first: ?string, second: string): string => {
export const semverMin = (first: ?string, second: string): string => {
return first && semver.lt(first, second) ? first : second;
};
@ -44,7 +44,16 @@ const getLowestVersions = (browsers: Array<string>): Targets => {
try {
// Browser version can return as "10.0-10.2"
const splitVersion = browserVersion.split("-")[0];
const splitVersion = browserVersion.split("-")[0].toLowerCase();
if (isUnreleasedVersion(splitVersion, browserName)) {
all[normalizedBrowserName] = getLowestUnreleased(
all[normalizedBrowserName],
splitVersion,
browserName,
);
}
const parsedBrowserVersion = semverify(splitVersion);
all[normalizedBrowserName] = semverMin(
@ -76,7 +85,12 @@ const outputDecimalWarning = (decimalTargets: Array<Object>): void => {
};
const targetParserMap = {
__default: (target, value) => [target, semverify(value)],
__default: (target, value) => {
const version = isUnreleasedVersion(value, target)
? value.toLowerCase()
: semverify(value);
return [target, version];
},
// Parse `node: true` and `node: "current"` to version
node: (target, value) => {

View File

@ -1,6 +1,8 @@
// @flow
import semver from "semver";
import unreleasedLabels from "../data/unreleased-labels";
import { semverMin } from "./targets-parser";
import type { Targets } from "./types";
// Convert version to a semver value.
@ -43,7 +45,8 @@ export const prettifyTargets = (targets: Targets): Object => {
return Object.keys(targets).reduce((results, target) => {
let value = targets[target];
if (typeof value === "string") {
const unreleasedLabel = unreleasedLabels[target];
if (typeof value === "string" && unreleasedLabel !== value) {
value = prettifyVersion(value);
}
@ -52,6 +55,26 @@ export const prettifyTargets = (targets: Targets): Object => {
}, {});
};
export const isUnreleasedVersion = (version: string, env: string): boolean => {
const unreleasedLabel = unreleasedLabels[env];
return (
unreleasedLabel && unreleasedLabel === version.toString().toLowerCase()
);
};
export const getLowestUnreleased = (
a: string,
b: string,
env: string,
): string => {
const unreleasedLabel = unreleasedLabels[env];
const hasUnreleased = [a, b].some(item => item === unreleasedLabel);
if (hasUnreleased) {
return a === hasUnreleased ? b : a || b;
}
return semverMin(a, b);
};
export const filterStageFromList = (list: any, stageList: any) => {
return Object.keys(list).reduce((result, item) => {
if (!stageList[item]) {

View File

@ -0,0 +1,4 @@
let n = { x, y, ...z };
try {
throw 0;
} catch {}

View File

@ -0,0 +1,9 @@
let n = {
x,
y,
...z
};
try {
throw 0;
} catch {}

View File

@ -0,0 +1,11 @@
{
"presets": [
["../../../../lib", {
"targets": {
"browsers": "safari tp"
},
"shippedProposals": true
}
]
]
}

View File

@ -0,0 +1 @@
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };

View File

@ -0,0 +1,10 @@
let {
x,
y,
...z
} = {
x: 1,
y: 2,
a: 3,
b: 4
};

View File

@ -0,0 +1,10 @@
{
"presets": [
["../../../../lib", {
"targets": {
"safari": "tp"
},
"shippedProposals": true
}]
]
}

View File

@ -39,6 +39,28 @@ describe("getTargets", () => {
);
});
it("works with TP versions", () => {
assert.deepEqual(
getTargets({
browsers: "safari tp",
}),
{
safari: "tp",
},
);
});
it("returns TP version in lower case", () => {
assert.deepEqual(
getTargets({
safari: "TP",
}),
{
safari: "tp",
},
);
});
it("ignores invalid", () => {
assert.deepEqual(
getTargets({