@babel/preset-env
@babel/preset-env 是一个智能预设,它允许你使用最新的 JavaScript ,而无需对目标环境需要哪些语法转换进行各种繁琐细节的管理。这不仅让你轻松,而且事 js 包更小!
Install
使用 npm :
npm install --save-dev @babel/preset-env
使用 yarn :
yarn add @babel/preset-env --dev
工作原理
如果不是一些很棒的开源项目,比如 browserslist, compat-table , 和 electron-chromium ,@babel/preset-env 将不会做到上面所说的一切。
我们依靠这些开源项目提供的数据,维护了两个映射,一个是不同版本的目标环境拥有的 js 特性或着浏览器特性,一个是 Babel 的转译插件和 core-js 的 polyfills 同 这些 js 特性和浏览器特性的映射。
注意:@babel/preset-env 不会包含任何低于 TC39 的第三阶段的 JavaScript 语法提案,因为此时绝对不会有浏览器支持。这些需要手动包含。设置 shippedProposals 选项将会包含一些浏览器已经实现的第三阶段提案。
在你设置任意目标环境后,@babel/preset-env 会根据上面说的映射关系检查你的代码,并生成一个插件列表传递给 Babel 。
生成 Browserslist
对于基于浏览器或者 Electron 的项目,我们建议使用 .browserslist 文件来指定目标环境。你可能会已经有这个配置文件了,因为它也被其他工具使用,比如 autoprefixer, stylelint, eslint-plugin-compat 等等。
默认情况下 @babel/preset-env 将使用 browserslist ,除非设置了 targets 或 ignoreBrowserslistConfig 选项。
例如,设置浏览器市场份额 >0.25% 用户的 polyfills 和代码转换。
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
]
]
}
Browserslist
> 0.25%
not dead
或者
Package.json
"browserslist": "> 0.25%, not dead"
选项
targets
string | Array<string> | { [string]: string }
,如果没有 browserslist ,默认最外层的 targets 选项,否则 {}。
它是描述你项目要支持的目标环境。
它可以是一个浏览器的用户范围:
{
"targets": "> 0.25%, not dead"
}
或具体某个产品的版本:
{
"targets": {
"chrome": "58",
"ie": "11"
}
}
示例环境: chrome
, opera
, edge
, firefox
, safari
, ie
, ios
, android
, node
, electron
.
没有 targets
由于 preset-env 的最初设计目标是帮助用户使用 preset-latest 轻松的过渡,因此在为指定 targets 时,preset-env 会将所有 ES2015-ES2020 的代码转化为 ES5 。
我们不建议以这种方式使用预设环境,因为它没有利用其针对特定目标环境版本的能力。
因此, preset-env 的行为与 browserslists 不同:当 Babel 没有 targets 配置或者没有 browserslists 配置,它不会默认查询,如果你想使用默认查询,你就需要显示的配置(browserslists的默认是 > 0.5%, last 2 versions, Firefox ESR, not dead ):
{
"presets": [["@babel/preset-env", { "targets": "defaults" }]]
}
如果你也想用 > 0.5%, last 2 versions, Firefox ESR, not dead ,就得显式配置。我们认识到这并不理想,Babel8将会重新考虑。
modules
"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false
,默认是 auto
。
是否将 ESM 转化为其他模块化标准。请注意,cjs 是 commonjs 的别名。
将此设置为 false 将保留 ESM 不受转换,仅当你打算将 ESM 用在浏览器上才用这个。如果你在 Babel 中使用 bundler ,建议你开启默认值。
useBuiltIns
"usage"
| "entry"
| false
, 默认是 false
。
这个选项配置 @babel/preset-env 如何使用 polyfills。
当这个配置选项为:usage
或 entry
,@babel/preset-env 会直接建立起对于 core-js 相关 module 的引用。因此这也意味着 core-js 会被解析为对应的相对路径同事需要确保 core-js 在你的项目中已经被安装了。
因为从 @babel/polyfill
从 7.4.0 版本开始就被弃用了,因此推荐直接配置 corejs
选项,并在项目当中直接安装 core-js
。
我的理解是,如果你只使用 entry,是需要手动引入 core-js 的,因为要在全局引入 polyfills 。使用 usage ,就相当于自动按需加载 polyfills,babel会默认使用 core-js@2 ,想使用@3的话,配置corejs
选项。
总结
@babel/preset-env 不是必须的,但不设置 Babel 就相当于没干活。