Skip to content

Commit

Permalink
Build the browser data from ES compatibility table (#8)
Browse files Browse the repository at this point in the history
Use the data from https://github.com/kangax/compat-table to build the
browser data.

Each Babel plugin is mapped to a list of features in the compatibility
table (in `data/pluginFeatures.js`), and the minimum supporting
version looked up from the compatibility test data. The script builds
the final browser data file in `data/plugins.json`.
  • Loading branch information
fson authored and hzoo committed Oct 6, 2016
1 parent 655ae2c commit 77a6d68
Show file tree
Hide file tree
Showing 6 changed files with 330 additions and 137 deletions.
126 changes: 126 additions & 0 deletions experimental/babel-preset-env/data/pluginFeatures.js
@@ -0,0 +1,126 @@
/* eslint-disable quotes */
module.exports = {
// es2015
"transform-es2015-arrow-functions": {
features: [
"arrow functions",
],
},
"transform-es2015-block-scoped-functions": {
features: [
"block-level function declaration"
],
},
"transform-es2015-block-scoping": {
features: [
"const",
"let",
],
},
"transform-es2015-classes": {
features: [
"class",
"super",
],
},
"transform-es2015-computed-properties": {
features: [
"object literal extensions / computed properties",
],
},
"check-es2015-constants": {
features: [
"const",
],
},
"transform-es2015-destructuring": {
features: [
"destructuring, assignment",
"destructuring, declarations",
"destructuring, parameters",
],
},
"transform-es2015-for-of": {
features: [
"for..of loops",
],
},
"transform-es2015-function-name": {
features: [
'function "name" property',
]
},
"transform-es2015-literals": {
features: [
"Unicode code point escapes",
],
},
"transform-es2015-object-super": {
features: [
"super",
],
},
"transform-es2015-parameters": {
features: [
"default function parameters",
"rest parameters",
],
},
"transform-es2015-shorthand-properties": {
features: [
"object literal extensions / shorthand properties",
],
},
"transform-es2015-spread": {
features: [
"spread (...) operator",
],
},
"transform-es2015-sticky-regex": {
features: [
'RegExp "y" and "u" flags / "y" flag, lastIndex',
'RegExp "y" and "u" flags / "y" flag',
],
},
"transform-es2015-template-literals": {
features: [
"template literals",
],
},
"transform-es2015-typeof-symbol": {
features: [
"Symbol / typeof support"
],
},
"transform-es2015-unicode-regex": {
features: [
'RegExp "y" and "u" flags / "u" flag, case folding',
'RegExp "y" and "u" flags / "u" flag, Unicode code point escapes',
'RegExp "y" and "u" flags / "u" flag',
],
},
"transform-regenerator": {
features: [
"generators",
],
},

// es2016
"transform-exponentiation-operator": {
features: [
"exponentiation (**) operator",
],
},

// es2017
"transform-async-to-generator": {
features: [
"async functions",
],
},
"syntax-trailing-function-commas": {
features: [
"trailing commas in function syntax",
],
}
};
117 changes: 117 additions & 0 deletions experimental/babel-preset-env/data/plugins.json
@@ -0,0 +1,117 @@
{
"transform-es2015-arrow-functions": {
"chrome": 47,
"edge": 13,
"firefox": 45,
"safari": 10
},
"transform-es2015-block-scoped-functions": {
"chrome": 41,
"firefox": 46,
"safari": 10
},
"transform-es2015-block-scoping": {
"chrome": 49,
"firefox": 51,
"safari": 10
},
"transform-es2015-classes": {
"chrome": 46,
"edge": 13,
"firefox": 45,
"safari": 10
},
"transform-es2015-computed-properties": {
"chrome": 44,
"edge": 12,
"firefox": 34,
"safari": 10
},
"check-es2015-constants": {
"chrome": 49,
"firefox": 51,
"safari": 10
},
"transform-es2015-destructuring": {
"chrome": 51,
"edge": 14,
"safari": 10
},
"transform-es2015-for-of": {
"chrome": 51,
"edge": 14,
"safari": 10
},
"transform-es2015-function-name": {
"chrome": 51,
"safari": 10
},
"transform-es2015-literals": {
"chrome": 44,
"edge": 12,
"safari": 9
},
"transform-es2015-object-super": {
"chrome": 46,
"edge": 13,
"firefox": 45,
"safari": 10
},
"transform-es2015-parameters": {
"chrome": 49,
"edge": 14,
"safari": 10
},
"transform-es2015-shorthand-properties": {
"chrome": 43,
"edge": 12,
"firefox": 33,
"safari": 9
},
"transform-es2015-spread": {
"chrome": 46,
"edge": 13,
"firefox": 36,
"safari": 10
},
"transform-es2015-sticky-regex": {
"chrome": 49,
"edge": 13,
"firefox": 3,
"safari": 10
},
"transform-es2015-template-literals": {
"chrome": 41,
"edge": 13,
"firefox": 34,
"safari": 9
},
"transform-es2015-typeof-symbol": {
"chrome": 38,
"edge": 12,
"firefox": 36,
"safari": 9
},
"transform-es2015-unicode-regex": {
"chrome": 50,
"edge": 13,
"firefox": 46,
"safari": 10
},
"transform-regenerator": {
"chrome": 50,
"edge": 13,
"safari": 10
},
"transform-exponentiation-operator": {
"chrome": 52,
"edge": 14
},
"transform-async-to-generator": {
"edge": 14
},
"syntax-trailing-function-commas": {
"edge": 14,
"safari": 10
}
}
14 changes: 9 additions & 5 deletions experimental/babel-preset-env/package.json
Expand Up @@ -8,10 +8,11 @@
"repository": "https://github.com/babel/babel-preset-env",
"main": "lib/index.js",
"scripts": {
"build": "babel src -d lib",
"build": "npm run build-data && babel src -d lib",
"build-data": "node ./scripts/build-data.js",
"dev": "babel -w src -d lib",
"lint": "eslint src test",
"fix": "eslint src test --fix",
"lint": "eslint scripts src test",
"fix": "eslint scripts src test --fix",
"ci": "npm run lint && npm run test",
"prepublish": "npm run build",
"test": "mocha ./test --compilers js:babel-register"
Expand Down Expand Up @@ -61,11 +62,14 @@
"babel-plugin-transform-flow-strip-types": "^6.8.0",
"babel-preset-es2015": "^6.14.0",
"babel-register": "^6.14.0",
"compat-table": "github:kangax/compat-table#gh-pages",
"eslint": "^3.3.1",
"eslint-config-babel": "^1.0.1",
"eslint-plugin-babel": "^3.3.0",
"eslint-plugin-flow-vars": "^0.5.0",
"mocha": "^3.0.2"
"lodash": "^4.15.0",
"mocha": "^3.0.2",
"natural-compare": "^1.4.0"
},
"babel": {
"presets": [
Expand All @@ -81,7 +85,7 @@
"transform-flow-strip-types"
]
},
"eslint": {
"eslintConfig": {
"extends": "babel",
"parserOptions": {
"ecmaVersion": 7,
Expand Down
77 changes: 77 additions & 0 deletions experimental/babel-preset-env/scripts/build-data.js
@@ -0,0 +1,77 @@
const fs = require("fs");
const path = require("path");

const flatten = require("lodash/flatten");
const flattenDeep = require("lodash/flattenDeep");
const naturalCompare = require("natural-compare");
const pluginFeatures = require("../data/pluginFeatures");

const renameTests = (tests, getName) =>
tests.map((test) => Object.assign({}, test, { name: getName(test.name) }));

const compatibilityTests = flattenDeep([
require("compat-table/data-es6"),
require("compat-table/data-es2016plus"),
].map((data) =>
data.tests.map((test) => {
return test.subtests ?
[test, renameTests(test.subtests, (name) => test.name + " / " + name)] :
test;
})
));

const versions = Object.keys(require("compat-table/data-es6").browsers)
.sort(naturalCompare);

const environments = [
"chrome",
"edge",
"firefox",
"safari",
];

const getLowestImplementedVersion = ({ features }, env) => {
let tests = flatten(compatibilityTests
.filter((test) => features.indexOf(test.name) >= 0)
.map((test) => {
return test.subtests ?
test.subtests.map((subtest) => subtest.res) :
test.res;
})
);

const envVersions = versions.filter((version) => version.startsWith(env));

for (let i = 0; i < envVersions.length; i++) {
const version = envVersions[i];
tests = tests.filter((test) =>
test[version] !== true &&
test[version] !== "strict"
);
if (tests.length === 0) {
const number = parseInt(version.replace(env, ""), 10);
return isFinite(number) ? number : null;
}
}
return null;
};

const data = {};
for (const pluginName in pluginFeatures) {
const options = pluginFeatures[pluginName];
const plugin = {};
environments.forEach((env) => {
if (Array.isArray(options.features)) {
const version = getLowestImplementedVersion(options, env);
if (version !== null) {
plugin[env] = version;
}
}
});
data[pluginName] = plugin;
}

fs.writeFileSync(
path.join(__dirname, "../data/plugins.json"),
JSON.stringify(data, null, 2) + "\n"
);
2 changes: 1 addition & 1 deletion experimental/babel-preset-env/src/index.js
Expand Up @@ -4,7 +4,7 @@
// "proto-to-assign",
// "es5-property-mutators",

import pluginList from "./plugins.js";
import pluginList from "../data/plugins.json";

export const plugins = [
"es3-member-expression-literals",
Expand Down

0 comments on commit 77a6d68

Please sign in to comment.