1 | # babel-preset-env [![npm](https://img.shields.io/npm/v/babel-preset-env.svg)](https://www.npmjs.com/package/babel-preset-env) [![travis](https://img.shields.io/travis/babel/babel-preset-env/master.svg)](https://travis-ci.org/babel/babel-preset-env) [![npm-downloads](https://img.shields.io/npm/dm/babel-preset-env.svg)](https://www.npmjs.com/package/babel-preset-env)
|
2 |
|
3 | > A Babel preset that can automatically determine the Babel plugins and polyfills you need based on your supported environments.
|
4 |
|
5 | ```sh
|
6 | npm install babel-preset-env --save-dev
|
7 | ```
|
8 |
|
9 | ```js
|
10 | {
|
11 | "presets": [
|
12 | ["env", {
|
13 | "targets": {
|
14 | "browsers": ["last 2 versions", "safari >= 7"]
|
15 | }
|
16 | }]
|
17 | ]
|
18 | }
|
19 | ```
|
20 |
|
21 | Check out the many options (especially `useBuiltIns` to polyfill less)!
|
22 |
|
23 | - [How it Works](#how-it-works)
|
24 | - [Install](#install)
|
25 | - [Usage](#usage)
|
26 | - [Options](#options)
|
27 | - [Examples](#examples)
|
28 | - [Caveats](#caveats)
|
29 | - [Other Cool Projects](#other-cool-projects)
|
30 |
|
31 | ## How it Works
|
32 |
|
33 | ### Determine environment support for ECMAScript features
|
34 |
|
35 | Use external data such as [`compat-table`](https://github.com/kangax/compat-table) to determine browser support. (We should create PRs there when necessary)
|
36 |
|
37 | ![](https://cloud.githubusercontent.com/assets/588473/19214029/58deebce-8d48-11e6-9004-ee3fbcb75d8b.png)
|
38 |
|
39 | We can periodically run [build-data.js](https://github.com/babel/babel-preset-env/blob/master/scripts/build-data.js) which generates [plugins.json](https://github.com/babel/babel-preset-env/blob/master/data/plugins.json).
|
40 |
|
41 | Ref: [#7](https://github.com/babel/babel-preset-env/issues/7)
|
42 |
|
43 | ### Maintain a mapping between JavaScript features and Babel plugins
|
44 |
|
45 | > Currently located at [plugin-features.js](https://github.com/babel/babel-preset-env/blob/master/data/plugin-features.js).
|
46 |
|
47 | This should be straightforward to do in most cases. There might be cases were plugins should be split up more or certain plugins aren't standalone enough (or impossible to do).
|
48 |
|
49 | ### Support all plugins in Babel that are considered `latest`
|
50 |
|
51 | > Default behavior without options is the same as `babel-preset-latest`.
|
52 |
|
53 | It won't include `stage-x` plugins. env will support all plugins in what we consider the latest version of Javascript (by matching what we do in [`babel-preset-latest`](http://babeljs.io/docs/plugins/preset-latest/)).
|
54 |
|
55 | Ref: [#14](https://github.com/babel/babel-preset-env/issues/14)
|
56 |
|
57 | ### Determine the lowest common denominator of plugins to be included in the preset
|
58 |
|
59 | If you are targeting IE 8 and Chrome 55 it will include all plugins required by IE 8 since you would need to support both still.
|
60 |
|
61 | ### Support a target option `"node": "current"` to compile for the currently running node version.
|
62 |
|
63 | For example, if you are building on Node 4, arrow functions won't be converted, but they will if you build on Node 0.12.
|
64 |
|
65 | ### Support a `browsers` option like autoprefixer
|
66 |
|
67 | Use [browserslist](https://github.com/ai/browserslist) to declare supported environments by performing queries like `> 1%, last 2 versions`.
|
68 |
|
69 | Ref: [#19](https://github.com/babel/babel-preset-env/pull/19)
|
70 |
|
71 | ## Install
|
72 |
|
73 | ```sh
|
74 | npm install --save-dev babel-preset-env
|
75 | ```
|
76 |
|
77 | ## Usage
|
78 |
|
79 | The default behavior without options runs all transforms (behaves the same as [babel-preset-latest](https://babeljs.io/docs/plugins/preset-latest/)).
|
80 |
|
81 | ```js
|
82 | {
|
83 | "presets": ["env"]
|
84 | }
|
85 | ```
|
86 |
|
87 | ## Options
|
88 |
|
89 | For more information on setting options for a preset, refer to the [plugin/preset options](http://babeljs.io/docs/plugins/#plugin-preset-options) documentation.
|
90 |
|
91 | ### `targets`
|
92 |
|
93 | `{ [string]: number }`, defaults to `{}`.
|
94 |
|
95 | Takes an object of environment versions to support.
|
96 |
|
97 | Each target environment takes a number (you can also specify a minor versions like `node: 6.5`)
|
98 |
|
99 | Example environments: `chrome`, `opera`, `edge`, `firefox`, `safari`, `ie`, `ios`, `android`, `node`, `electron`.
|
100 |
|
101 | The [data](https://github.com/babel/babel-preset-env/blob/master/data/plugins.json) for this is generated by running the [build-data script](https://github.com/babel/babel-preset-env/blob/master/scripts/build-data.js) which pulls in data from [compat-table](https://kangax.github.io/compat-table).
|
102 |
|
103 | ### `targets.node`
|
104 |
|
105 | `number | "current" | true`
|
106 |
|
107 | If you want to compile against the current node version, you can specify `"node": true` or `"node": "current"`, which would be the same as `"node": parseFloat(process.versions.node)`.
|
108 |
|
109 | ### `targets.browsers`
|
110 |
|
111 | `Array<string> | string`
|
112 |
|
113 | A query to select browsers (ex: last 2 versions, > 5%) using [browserslist](https://github.com/ai/browserslist).
|
114 |
|
115 | Note, browsers' results are overridden by explicit items from `targets`.
|
116 |
|
117 | ### `loose`
|
118 |
|
119 | `boolean`, defaults to `false`.
|
120 |
|
121 | Enable "loose" transformations for any plugins in this preset that allow them.
|
122 |
|
123 | ### `modules`
|
124 |
|
125 | `"amd" | "umd" | "systemjs" | "commonjs" | false`, defaults to `"commonjs"`.
|
126 |
|
127 | Enable transformation of ES6 module syntax to another module type.
|
128 |
|
129 | Setting this to `false` will not transform modules.
|
130 |
|
131 | ### `debug`
|
132 |
|
133 | `boolean`, defaults to `false`.
|
134 |
|
135 | Outputs the targets/plugins used and the version specified in [plugin data version](https://github.com/babel/babel-preset-env/blob/master/data/plugins.json) to `console.log`.
|
136 |
|
137 | ### `include`
|
138 |
|
139 | `Array<string>`, defaults to `[]`.
|
140 |
|
141 | > NOTE: `whitelist` is deprecated and will be removed in the next major in favor of this.
|
142 |
|
143 | An array of plugins to always include.
|
144 |
|
145 | Valid options include any of the [babel plugins](https://github.com/babel/babel-preset-env/blob/master/data/plugin-features.js) or [built-ins](https://github.com/babel/babel-preset-env/blob/master/data/built-in-features.js), such as `transform-es2015-arrow-functions`, `map`, `set`, or `object.assign`.
|
146 |
|
147 | This option is useful if there is a bug in a native implementation, or a combination of a non-supported feature + a supported one doesn't work.
|
148 |
|
149 | For example, Node 4 supports native classes but not spread. If `super` is used with a spread argument, then the `transform-es2015-classes` transform needs to be `include`d, as it is not possible to transpile a spread with `super` otherwise.
|
150 |
|
151 | ### `exclude`
|
152 |
|
153 | `Array<string>`, defaults to `[]`.
|
154 |
|
155 | An array of plugins to always exclude/remove.
|
156 |
|
157 | The possible options are the same as the `include` option.
|
158 |
|
159 | This option is useful for "blacklisting" a transform like `transform-regenerator` if you don't use generators and don't want to include `regeneratorRuntime` (when using `useBuiltIns`) or for using another plugin like [fast-async](https://github.com/MatAtBread/fast-async) instead of [Babel's async-to-gen](http://babeljs.io/docs/plugins/transform-async-generator-functions/).
|
160 |
|
161 | ### `useBuiltIns`
|
162 |
|
163 | `boolean`, defaults to `false`.
|
164 |
|
165 | A way to apply `babel-preset-env` for polyfills (via "babel-polyfill").
|
166 |
|
167 | > NOTE: This does not currently polyfill experimental/stage-x built-ins like the regular "babel-polyfill" does.
|
168 | > This will only work with npm >= 3 (which should be used with Babel 6 anyway)
|
169 |
|
170 | ```
|
171 | npm install babel-polyfill --save
|
172 | ```
|
173 |
|
174 | This option enables a new plugin that replaces the statement `import "babel-polyfill"` or `require("babel-polyfill")` with individual requires for `babel-polyfill` based on environment.
|
175 |
|
176 | > NOTE: Only use `require("babel-polyfill");` once in your whole app. One option is to create a single entry file that only contains the require statement.
|
177 |
|
178 | **In**
|
179 |
|
180 | ```js
|
181 | import "babel-polyfill";
|
182 | ```
|
183 |
|
184 | **Out (different based on environment)**
|
185 |
|
186 | ```js
|
187 | import "core-js/modules/es7.string.pad-start";
|
188 | import "core-js/modules/es7.string.pad-end";
|
189 | import "core-js/modules/web.timers";
|
190 | import "core-js/modules/web.immediate";
|
191 | import "core-js/modules/web.dom.iterable";
|
192 | ```
|
193 |
|
194 | This will also work for `core-js` directly (`import "core-js";`)
|
195 |
|
196 | ```
|
197 | npm install core-js --save
|
198 | ```
|
199 |
|
200 | ---
|
201 |
|
202 | ## Examples
|
203 |
|
204 | ```js
|
205 | // src
|
206 | export class A {}
|
207 | ```
|
208 |
|
209 | ```js
|
210 | // target chrome 52
|
211 | {
|
212 | "presets": [
|
213 | ["env", {
|
214 | "targets": {
|
215 | "chrome": 52
|
216 | }
|
217 | }]
|
218 | ]
|
219 | }
|
220 |
|
221 | // ...
|
222 |
|
223 | class A {}
|
224 | exports.A = A;
|
225 | ```
|
226 |
|
227 | ```js
|
228 | // target chrome 52 with webpack 2/rollup and loose mode
|
229 | {
|
230 | "presets": [
|
231 | ["env", {
|
232 | "targets": {
|
233 | "chrome": 52
|
234 | },
|
235 | "modules": false,
|
236 | "loose": true
|
237 | }]
|
238 | ]
|
239 | }
|
240 |
|
241 | // ...
|
242 |
|
243 | export class A {}
|
244 | ```
|
245 |
|
246 | ```js
|
247 | // using browserslist
|
248 | {
|
249 | "presets": [
|
250 | ["env", {
|
251 | "targets": {
|
252 | "chrome": 52,
|
253 | "browsers": ["last 2 versions", "safari 7"]
|
254 | }
|
255 | }]
|
256 | ]
|
257 | }
|
258 |
|
259 | // ...
|
260 |
|
261 | export var A = function A() {
|
262 | _classCallCheck(this, A);
|
263 | };
|
264 | ```
|
265 |
|
266 | ### Example with `node: true` or `node: "current"`
|
267 |
|
268 | ```js
|
269 | // process.versions.node -> 6.9.0
|
270 | {
|
271 | "presets": [
|
272 | ["env", {
|
273 | "targets": {
|
274 | "node": "current"
|
275 | }
|
276 | }]
|
277 | ]
|
278 | }
|
279 |
|
280 | // ...
|
281 |
|
282 | class A {}
|
283 | exports.A = A;
|
284 | ```
|
285 |
|
286 | ### Example with `debug: true`
|
287 |
|
288 | ```js
|
289 | Using targets: {
|
290 | "node": 6.5
|
291 | }
|
292 |
|
293 | Using plugins:
|
294 |
|
295 | module: false
|
296 | transform-exponentiation-operator {}
|
297 | transform-async-to-generator {}
|
298 | syntax-trailing-function-commas {}
|
299 | ```
|
300 |
|
301 | ### Example with `include`/`exclude`
|
302 |
|
303 | > always include arrow functions, explicitly exclude generators
|
304 |
|
305 | ```js
|
306 | {
|
307 | "presets": [
|
308 | ["env", {
|
309 | "targets": {
|
310 | "browsers": ["last 2 versions", "safari >= 7"]
|
311 | },
|
312 | "include": ["transform-es2015-arrow-functions", "es6.map"],
|
313 | "exclude": ["transform-regenerator", "es6.set"]
|
314 | }]
|
315 | ]
|
316 | }
|
317 | ```
|
318 |
|
319 | ## Caveats
|
320 |
|
321 | If you get a `SyntaxError: Unexpected token ...` error when using the [object-rest-spread](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-object-rest-spread) transform then make sure the plugin has been updated to, at least, `v6.19.0`.
|
322 |
|
323 | ## Other Cool Projects
|
324 |
|
325 | - [auto-babel](https://github.com/jakepusateri/auto-babel)
|
326 | - [babel-preset-target](https://github.com/sdkennedy/babel-preset-target)
|
327 | - [babel-preset-modern-node](https://github.com/michaelcontento/babel-preset-modern-node)
|
328 | - [babel-preset-modern-browsers](https://github.com/christophehurpeau/babel-preset-modern-browsers)
|
329 | - ?
|