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 | ```json
|
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 | With [npm](https://www.npmjs.com):
|
74 |
|
75 | ```sh
|
76 | npm install --save-dev babel-preset-env
|
77 | ```
|
78 |
|
79 | Or [yarn](https://yarnpkg.com):
|
80 |
|
81 | ```sh
|
82 | yarn add babel-preset-env --dev
|
83 | ```
|
84 |
|
85 | ## Usage
|
86 |
|
87 | The default behavior without options runs all transforms (behaves the same as [babel-preset-latest](https://babeljs.io/docs/plugins/preset-latest/)).
|
88 |
|
89 | ```json
|
90 | {
|
91 | "presets": ["env"]
|
92 | }
|
93 | ```
|
94 |
|
95 | ## Options
|
96 |
|
97 | For more information on setting options for a preset, refer to the [plugin/preset options](http://babeljs.io/docs/plugins/#plugin-preset-options) documentation.
|
98 |
|
99 | ### `targets`
|
100 |
|
101 | `{ [string]: number }`, defaults to `{}`.
|
102 |
|
103 | Takes an object of environment versions to support.
|
104 |
|
105 | Each target environment takes a number (you can also specify a minor versions like `node: 6.5`)
|
106 |
|
107 | Example environments: `chrome`, `opera`, `edge`, `firefox`, `safari`, `ie`, `ios`, `android`, `node`, `electron`.
|
108 |
|
109 | 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).
|
110 |
|
111 | ### `targets.node`
|
112 |
|
113 | `number | "current" | true`
|
114 |
|
115 | 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)`.
|
116 |
|
117 | ### `targets.browsers`
|
118 |
|
119 | `Array<string> | string`
|
120 |
|
121 | A query to select browsers (ex: last 2 versions, > 5%) using [browserslist](https://github.com/ai/browserslist).
|
122 |
|
123 | Note, browsers' results are overridden by explicit items from `targets`.
|
124 |
|
125 | ### `loose`
|
126 |
|
127 | `boolean`, defaults to `false`.
|
128 |
|
129 | Enable "loose" transformations for any plugins in this preset that allow them.
|
130 |
|
131 | ### `modules`
|
132 |
|
133 | `"amd" | "umd" | "systemjs" | "commonjs" | false`, defaults to `"commonjs"`.
|
134 |
|
135 | Enable transformation of ES6 module syntax to another module type.
|
136 |
|
137 | Setting this to `false` will not transform modules.
|
138 |
|
139 | ### `debug`
|
140 |
|
141 | `boolean`, defaults to `false`.
|
142 |
|
143 | 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`.
|
144 |
|
145 | ### `include`
|
146 |
|
147 | `Array<string>`, defaults to `[]`.
|
148 |
|
149 | > NOTE: `whitelist` is deprecated and will be removed in the next major in favor of this.
|
150 |
|
151 | An array of plugins to always include.
|
152 |
|
153 | 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`.
|
154 |
|
155 | 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.
|
156 |
|
157 | 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.
|
158 |
|
159 | ### `exclude`
|
160 |
|
161 | `Array<string>`, defaults to `[]`.
|
162 |
|
163 | An array of plugins to always exclude/remove.
|
164 |
|
165 | The possible options are the same as the `include` option.
|
166 |
|
167 | 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/).
|
168 |
|
169 | ### `useBuiltIns`
|
170 |
|
171 | `boolean`, defaults to `false`.
|
172 |
|
173 | A way to apply `babel-preset-env` for polyfills (via "babel-polyfill").
|
174 |
|
175 | > NOTE: This does not currently polyfill experimental/stage-x built-ins like the regular "babel-polyfill" does.
|
176 | > This will only work with npm >= 3 (which should be used with Babel 6 anyway)
|
177 |
|
178 | ```
|
179 | npm install babel-polyfill --save
|
180 | ```
|
181 |
|
182 | 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.
|
183 |
|
184 | > 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.
|
185 |
|
186 | **In**
|
187 |
|
188 | ```js
|
189 | import "babel-polyfill";
|
190 | ```
|
191 |
|
192 | **Out (different based on environment)**
|
193 |
|
194 | ```js
|
195 | import "core-js/modules/es7.string.pad-start";
|
196 | import "core-js/modules/es7.string.pad-end";
|
197 | import "core-js/modules/web.timers";
|
198 | import "core-js/modules/web.immediate";
|
199 | import "core-js/modules/web.dom.iterable";
|
200 | ```
|
201 |
|
202 | This will also work for `core-js` directly (`import "core-js";`)
|
203 |
|
204 | ```
|
205 | npm install core-js --save
|
206 | ```
|
207 |
|
208 | ---
|
209 |
|
210 | ## Examples
|
211 |
|
212 | ### Export with various targets
|
213 |
|
214 | ```js
|
215 | export class A {}
|
216 | ```
|
217 |
|
218 | #### Target only Chrome 52
|
219 |
|
220 | **.babelrc**
|
221 |
|
222 | ```json
|
223 | {
|
224 | "presets": [
|
225 | ["env", {
|
226 | "targets": {
|
227 | "chrome": 52
|
228 | }
|
229 | }]
|
230 | ]
|
231 | }
|
232 | ```
|
233 |
|
234 | **Out**
|
235 |
|
236 | ```js
|
237 | class A {}
|
238 | exports.A = A;
|
239 | ```
|
240 |
|
241 | #### Target Chrome 52 with webpack 2/rollup and loose mode
|
242 |
|
243 | **.babelrc**
|
244 |
|
245 | ```json
|
246 | {
|
247 | "presets": [
|
248 | ["env", {
|
249 | "targets": {
|
250 | "chrome": 52
|
251 | },
|
252 | "modules": false,
|
253 | "loose": true
|
254 | }]
|
255 | ]
|
256 | }
|
257 | ```
|
258 |
|
259 | **Out**
|
260 |
|
261 | ```js
|
262 | export class A {}
|
263 | ```
|
264 |
|
265 | #### Target specific browsers via browserslist
|
266 |
|
267 | **.babelrc**
|
268 |
|
269 | ```json
|
270 | {
|
271 | "presets": [
|
272 | ["env", {
|
273 | "targets": {
|
274 | "chrome": 52,
|
275 | "browsers": ["last 2 versions", "safari 7"]
|
276 | }
|
277 | }]
|
278 | ]
|
279 | }
|
280 | ```
|
281 |
|
282 | **Out**
|
283 |
|
284 | ```js
|
285 | export var A = function A() {
|
286 | _classCallCheck(this, A);
|
287 | };
|
288 | ```
|
289 |
|
290 | #### Target latest node via `node: true` or `node: "current"`
|
291 |
|
292 | **.babelrc**
|
293 |
|
294 | ```json
|
295 | {
|
296 | "presets": [
|
297 | ["env", {
|
298 | "targets": {
|
299 | "node": "current"
|
300 | }
|
301 | }]
|
302 | ]
|
303 | }
|
304 | ```
|
305 |
|
306 | **Out**
|
307 |
|
308 | ```js
|
309 | class A {}
|
310 | exports.A = A;
|
311 | ```
|
312 |
|
313 | ### Show debug output
|
314 |
|
315 | **.babelrc**
|
316 |
|
317 | ```json
|
318 | {
|
319 | "presets": [
|
320 | [ "env", {
|
321 | "targets": {
|
322 | "safari": 10
|
323 | },
|
324 | "modules": false,
|
325 | "useBuiltIns": true,
|
326 | "debug": true
|
327 | }]
|
328 | ]
|
329 | }
|
330 | ```
|
331 |
|
332 | **stdin**
|
333 |
|
334 | ```sh
|
335 | Using targets:
|
336 | {
|
337 | "safari": 10
|
338 | }
|
339 |
|
340 | Modules transform: false
|
341 |
|
342 | Using plugins:
|
343 | transform-exponentiation-operator {}
|
344 | transform-async-to-generator {}
|
345 |
|
346 | Using polyfills:
|
347 | es7.object.values {}
|
348 | es7.object.entries {}
|
349 | es7.object.get-own-property-descriptors {}
|
350 | web.timers {}
|
351 | web.immediate {}
|
352 | web.dom.iterable {}
|
353 | ```
|
354 |
|
355 | ### Include and exclude specific plugins/built-ins
|
356 |
|
357 | > always include arrow functions, explicitly exclude generators
|
358 |
|
359 | ```json
|
360 | {
|
361 | "presets": [
|
362 | ["env", {
|
363 | "targets": {
|
364 | "browsers": ["last 2 versions", "safari >= 7"]
|
365 | },
|
366 | "include": ["transform-es2015-arrow-functions", "es6.map"],
|
367 | "exclude": ["transform-regenerator", "es6.set"]
|
368 | }]
|
369 | ]
|
370 | }
|
371 | ```
|
372 |
|
373 | ## Caveats
|
374 |
|
375 | 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`.
|
376 |
|
377 | ## Other Cool Projects
|
378 |
|
379 | - [auto-babel](https://github.com/jakepusateri/auto-babel)
|
380 | - [babel-preset-target](https://github.com/sdkennedy/babel-preset-target)
|
381 | - [babel-preset-modern-node](https://github.com/michaelcontento/babel-preset-modern-node)
|
382 | - [babel-preset-modern-browsers](https://github.com/christophehurpeau/babel-preset-modern-browsers)
|
383 | - ?
|