@babel/preset-env

翻译自:https://babeljs.io/docs/en/babel-preset-env
Babel 7.0.0
@babel/preset-env 是一个智能preset,它使用最新的javascript规则,而不用因为环境不同(chrome,FF),调整对应的语法转化(和可选的浏览器polyfills)。这样可以更加便捷,你的bundles更加小。

安装

可通过npm

1
npm install --save-dev @babel/preset-env

可通过yarn

1
yarn add @babel/preset-env --dev

工作方式

若不是因为很多很棒的开源项目,比如browserslist, compat-table, 和 electron-to-chromium,@babel/preset-env就不会有。

我们通过那些开源项目,形成一个关于环境版本和javascript语法、浏览器功能的映射。@babel/preset-env会获取你指定的环境版本(https://babeljs.io/docs/en/babel-preset-env#targets),根据他的映射与检查,从而获得关于编译的plugin的列表,然后传给babel。(@babel/preset-env会拿你的指定版本,到字典里面去查找,找出对应的版本所需的编译插件,然后传递给babel)。

浏览器集成

对于支持浏览器或者桌面应用的项目,我们推荐你用.browserslistrc(https://github.com/browserslist/browserslist)文件与指定目标。可能在你的文件目录里已经有了这个文件,因为这个文件在很多工具里都存在,比如autoprefixer, stylelint, eslint-plugin-compat等。

@babel/preset-env默认会用browserslist的config,除非你设置了targets或者ignoreBrowserslistConfig。

栗子:只关心大于0.25%的市场需求,所需的polyfills和code transforms。
.babelrc

1
2
3
4
5
6
7
8
9
10
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
]
]
}

.browserslistrc

1
2
> 0.25%
not dead

或者可以直接在package.json里设置

1
"browserslist": "> 0.25%, not dead"

选项

关于perset更多的配置,可以查看plugin/preset options文档(http://babeljs.io/docs/en/plugins/#plugin-preset-options)

target

string | Array<string> | { [string]: string }, defaults to {}.
描述你的项目所支持的环境。这个也可以是browserslist-compatible查询:

1
2
3
{
"targets": "> 0.25%, not dead"
}

也可以是项目支持的最低浏览器版本:

1
2
3
4
5
6
{
"targets": {
"chrome": "58",
"ie": "11"
}
}

以上表示chrome至少是58版本,ie至少是11版本。chrome, opera, edge, firefox, safari, ie, ios, android, node, electron这些是可选项。
PS:如果targets没有定义,@babel/preset-env的效果是和@babel/preset-es2015, @babel/preset-es2016, @babel/preset-es2017共同作用的效果是一样一样的。然而,我们并不推荐这种方式使用preset-env(如下),因为他并没有发挥他可以指定环境版本的优势。

1
2
3
{
"presets": ["@babel/preset-env"]
}

targets.esmodules

boolean
你的目标浏览器可能支持ES Modules,当定义了targets.esmodules后,targets.browsers就会被忽略。你可以利用这个方案,结合<script type="module"></script>去合成更小的bundler包。

1
2
3
4
5
6
7
8
9
10
11
12
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"esmodules": true
}
}
]
]
}

targets.node

string | "current" | true
如果你想针对当前node版本编译,你可以指定”node”: true或者”node”: “current”,或者”node”: process.versions.node

targets.safari

string | "tp"
如果你想针对Safari的technology preview 版本,你可以指定”safari”: “tp”。

targets.browser(在最后一个版本废弃,直接用target)

string | Array
基于browserlist的一个浏览器选择器。(比方说:last 2 versions, > 5%, safari tp:最近2个版本,市场份额>5%,支持safari tp)。

spec

boolean, defaults to false
允许更加规范的兼容。但是对于支持它的插件来说,转换的比较慢

loose

boolean, defaults to false
允许支持loose转化(http://2ality.com/2015/12/babel6-loose-mode.html)的任何presets插件。

modules

"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | false, defaults to "commonjs".
将ES6转化成任意module type,当设置成false的时候,他不会转化。

debug

boolean, defaults to false
将使用的targets/plugins 和插件数据版本中指定的版本(https://github.com/babel/babel/blob/master/packages/babel-preset-env/data/plugins.json)输出到console.log

include

Array<string|RegExp>, defaults to []
一系列总是包含的插件。这个功能对于某些场景是比较有用的。比如原生实现中存在bug,或者一个不支持的功能和支持的功能组合起来不起作用。比方说,Node4支持原生class,但是不知道spread,如果super用在了spread参数里。这时,@babel/plugin-transform-classes需要设置在include选项中。否则他就没法转化带有super的spread了。

exclude

Array<string|RegExp>, defaults to []
一些列总是要移出的插件。这个选项只用于『黑名单』转化。比如说,你不需要用到generators,同时不想要regeneratorRuntime,你可以把@babel/plugin-transform-regenerator写在exclude里。或者利用其他插件比如fast-async替代Babel’s async-to-gen。

useBuiltIns

“usage” | “entry” | false, defaults to false
这个选项为导入core-js模块添加引用。因此会解决文件本身关于core-js的问题。如果没有core-js的依赖,或者是有其他版本,就可能需要在你的应用最开头中指定core-js@2的依赖。
这个选项指名@babel/preset-env如何处理polyfills的。

useBuiltIns: ‘entry’

NOTE: 在你整个app只需要require一次require(“@babel/polyfill”),否则就会有问题。
这个选项是开启了一个插件,即将文件中的import “@babel/polyfill”或require(“@babel/polyfill”)替换成基于环境的独立的需求。
如下:
In:

1
import "@babel/polyfill";

Out (different based on environment):

1
2
import "core-js/modules/es7.string.pad-start";
import "core-js/modules/es7.string.pad-end";

useBuiltIns: ‘usage’ (experimental)

每个文件中添加指定polyfill。我们可以利用一个bundler只会加载一次polyfill。
In:
a.js

1
2
var a = new Promise();
`

b.js

1
var b = new Map();

Out (如果运行环境不支持):

1
2
import "core-js/modules/es6.promise";
var a = new Promise();

1
2
import "core-js/modules/es6.map";
var b = new Map();

Out (如果运行环境支持):

1
var a = new Promise();

1
var b = new Map();

useBuiltIns: false

不会为文件自动添加polyfills,或者将import “@babel/polyfill”转化成适合环境的polyfills。

forceAllTransforms

boolean, defaults to false.
利用Babel 7的Javascipt config file(https://babeljs.io/docs/en/config-files#javascript)支持,可以允许在production的环境下强制转化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module.exports = function(api) {
return {
presets: [
[
"@babel/preset-env",
{
targets: {
chrome: 59,
edge: 13,
firefox: 50,
},
// for uglifyjs...
forceAllTransforms: api.env("production"),
},
],
],
};
};

默认情况下,这个preset会对指定环境做polyfills。 如果你想对所有做强制转化,你可以打开它。

configPath

string, defaults to process.cwd()
.browserslistrc的文件目录,如果没找到,就从他的上级文件找。直到找到为止。