Skip to content
This repository has been archived by the owner on May 11, 2018. It is now read-only.

Adds browsers property to use browserslist's queries #19

Merged
merged 12 commits into from
Oct 13, 2016
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,24 @@ The data for this is currently at: [/data/plugins.json](/data/plugins.json) and

Currently: "chrome, edge, firefox, safari, node"

> Some node features are > `6.5`
> Some node features are > `6.5`.

* `browsers` (array/string) - an query to select browsers (ex: last 2 versions, > 5%).

> Note, browsers' results are overridden by explicit items from `targets`.

* `loose` (boolean) - Enable "loose" transformations for any plugins in this preset that allow them (Disabled by default).
* `modules` - Enable transformation of ES6 module syntax to another module type (Enabled by default to `"commonjs"`).
* Can be `false` to not transform modules, or one of `["amd", "umd", "systemjs", "commonjs"]`
* `debug` (boolean) - `console.log` out the targets and plugins being used as well as the version specified in `/data/plugins.json`
* Can be `false` to not transform modules, or one of `["amd", "umd", "systemjs", "commonjs"]`.
* `debug` (boolean) - `console.log` out the targets and plugins being used as well as the version specified in `/data/plugins.json`.

```js
{
"presets": [
["env", {
"targets": {
"chrome": 52
"chrome": 52,
"browsers": "last 2 safari versions"
},
"loose": true,
"modules": false
Expand Down Expand Up @@ -99,6 +104,24 @@ exports.A = A;
export class A {}
```

```js
// using browserslist
{
"presets": [
["env", {
"targets": {
"chrome": 52,
"browsers": ["last 2 versions", "safari 7"]
}
}]
]
}

// ...

export class A {}
```

### Example with `debug: true`

```js
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
"babel-plugin-transform-es2015-typeof-symbol": "^6.6.0",
"babel-plugin-transform-es2015-unicode-regex": "^6.3.13",
"babel-plugin-transform-exponentiation-operator": "^6.8.0",
"babel-plugin-transform-regenerator": "^6.6.0"
"babel-plugin-transform-regenerator": "^6.6.0",
"browserslist": "^1.4.0"
},
"devDependencies": {
"babel-cli": "^6.11.4",
Expand Down
33 changes: 32 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// "es5-property-mutators",

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

export const plugins = [
"es3-member-expression-literals",
Expand Down Expand Up @@ -39,6 +40,10 @@ export const MODULE_TRANSFORMATIONS = {
* @return {Boolean} Whether or not the transformation is required
*/
export const isPluginRequired = (supportedEnvironments, plugin) => {
if (supportedEnvironments.browsers) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary?

The code that calls this does

 const targets = getTargets(opts.targets);
isPluginRequired(targets, pluginList[pluginName]));

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hzoo It's just for usage from a separate module. When options are not handled yet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left it in buildPreset to prevent running getTargets method for each item from pluginList

supportedEnvironments = getTargets(supportedEnvironments);
}

const targetEnvironments = Object.keys(supportedEnvironments);

if (targetEnvironments.length === 0) { return true; }
Expand All @@ -61,8 +66,34 @@ export const isPluginRequired = (supportedEnvironments, plugin) => {
return isRequiredForEnvironments.length > 0 ? true : false;
};

const isBrowsersQueryValid = browsers => {
return typeof browsers === "string" || Array.isArray(browsers);
};

const getLowestVersions = (browsers) => {
return browsers.reduce((all, browser) => {
const [browserName, browserVersion] = browser.split(" ");
all[browserName] = parseInt(browserVersion);
return all;
}, {});
};

const mergeBrowsers = (fromQuery, fromTarget) => {
return Object.keys(fromTarget).reduce((queryObj, targKey) => {
if (targKey !== "browsers") {
queryObj[targKey] = fromTarget[targKey];
}
return queryObj;
}, fromQuery);
};

const getTargets = targetOpts => {
return targetOpts || {};
const browserOpts = targetOpts.browsers;
if (isBrowsersQueryValid(browserOpts)) {
const queryBrowsers = getLowestVersions(browserslist(browserOpts));
return mergeBrowsers(queryBrowsers, targetOpts);
}
return targetOpts;
};

// TODO: Allow specifying plugins as either shortened or full name
Expand Down
32 changes: 32 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,38 @@ describe("babel-preset-env", () => {
assert(babelPresetEnv.isPluginRequired(targets, plugin) === true);
});

it("returns false if plugin feature is implemented by lower than target defined in browsers query", () => {
const plugin = {
chrome: 49,
};
const targets = {
"browsers": "chrome > 50"
};
assert(babelPresetEnv.isPluginRequired(targets, plugin) === false);
});

it("returns true if plugin feature is implemented is greater than target defined in browsers query", () => {
const plugin = {
chrome: 52,
};
const targets = {
"browsers": "chrome > 50"
};
assert(babelPresetEnv.isPluginRequired(targets, plugin) === true);
});

it("returns true if target's root items overrides versions defined in browsers query", () => {
const plugin = {
chrome: 45,
};
const targets = {
browsers: "last 2 Chrome versions",
chrome: 44
};

assert(babelPresetEnv.isPluginRequired(targets, plugin) === true);
});

it("doesn't throw when specifiying a decimal for node", () => {
let targets;
const plugin = {
Expand Down