# @babel/预设环境
@babel/preset-env
是一个“聪明”的预设(preset),它能让你使用最新的 JavaScript 语法而无需操心对目标环境所支持的语法设置相应的语法转换插件(以及可选的 polyfills)。这样能让你的工作更轻松,也能让打出来的 JavaScript 包更小!
安装
工作原理
与 Browserslist 集成
参数
# 安装 (opens new window)
- npm
npm install --save-dev @babel/preset-env
- yarn
yarn add --dev @babel/preset-env
# 工作原理 (opens new window)
@babel/preset-env
是构建其它的优秀开源项目之上的,例如 browserslist
、compat-table (opens new window) 以及 electron-to-chromium
等。
我们利用这些数据源来维护我们支持的目标环境版本 (opens new window) 获得 JavaScript 语法或浏览器功能支持的映射,以及这些语法和功能到 Babel 转换插件和 core-js polyfill 的映射。
注意:
@babel/preset-env
不包含任何未进入 Stage 3 阶段的 JavaScript 语法提案,因为在 TC39 的流程中,未进入 Stage 3 阶段的提案是不会被任何浏览器所实现的。如果确有需要,请手动设置。通过设置shippedProposals
参数可以包含进入 Stage 3 阶段并且已经被部分浏览器实现的提案。
@babel/preset-env
获取您指定的任何目标环境 (opens new window) 并根据其映射检查它们以编译插件列表并将其传递给 Babel。
# 与 Browserslist 集成 (opens new window)
对于基于浏览器或 Electron 的项目,我们建议使用 .browserslistrc
文件来指定目标环境。你可能已经有这个配置文件了,因为 JavaScript 生态中的其它工具也支持该配置文件,例如 autoprefixer
、stylelint (opens new window) 、eslint-plugin-compat (opens new window) 等等。
默认情况下,@babel/preset-env
将使用 browserslist 配置文件
, 除非设置了 targets
或 ignoreBrowserslistConfig
参数。
请注意,如果您依赖 browserslist 的默认查询(明确地或没有 browserslist 配置),您将需要查看 No
targets
部分以获取有关 preset-env 行为的信息。
例如,仅包括浏览器市场份额 >0.25% 的用户所需的 polyfill 和代码转换(忽略没有安全更新的浏览器,如 IE 10 和黑莓):
babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry",
"corejs": "3.22"
}
]
]
}
.browserslistrc
> 0.25%
not dead
或者
包.json
{ "browserslist": "> 0.25%, not dead" }
请注意,从
v7.4.5
版本开始,browserslist 查询 is resolved withmobileToDesktop: true
. 例如,如果 if you want to create a snapshot of a query runnpx browserslist --mobile-to-desktop ">0.25%, not dead"
.
# 参数 (opens new window)
有关预设设置选项的更多信息,请参阅预设选项 (opens new window) 文档。
# targets
(opens new window)
string | Array<string> | { [string]: string }
, 如果在的文档targets
中未指定与浏览器列表相关的选项,则默认为顶级选项,否则为.@babel/preset-env``{}
使用方法请参考targets选件 (opens new window) 文档。
# bugfixes
(opens new window)
boolean
, 默认为false
.
添加于:v7.9.0
注意:这些优化将在 Babel 8 中默认启用
默认情况下,@babel/preset-env
(以及一般的 Babel 插件)将 ECMAScript 语法特性分组为密切相关的较小特性的集合。这些组可能很大并且包含很多边缘情况,例如“函数参数”包括解构的、默认的和剩余的参数。从这些分组信息中,Babel 会根据您指定给 选项的浏览器支持目标来启用或禁用每个@babel/preset-env
组targets
。
启用此选项后,尝试将损坏的语法编译为目标浏览器支持的@babel/preset-env
最接近的未损坏的现代语法。根据您targets
以及您使用的现代语法的数量,这可能会导致编译后的应用程序的大小显着减少。@babel/preset-modules (opens new window) 此选项合并了无需使用其他预设的功能。
# spec
(opens new window)
boolean
, 默认为false
.
为支持它们的此预设中的任何插件启用更符合规范但可能更慢的转换。
# loose
(opens new window)
boolean
, 默认为false
.
为该预设中允许它们的任何插件启用“松散”转换。 (opens new window)
assumptions
⚠️ 考虑迁移到自 Babel 7.13 以来可用的顶层。
# modules
(opens new window)
"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false
, 默认为"auto"
.
启用 ES 模块语法到另一种模块类型的转换。请注意,这cjs
只是commonjs
.
将此设置为false
将保留 ES 模块。仅当您打算将本机 ES 模块发送到浏览器时才使用它。如果你使用 Babel 的打包器,默认的modules: "auto"
总是首选。
# modules: "auto"
(opens new window)
默认情况下@babel/preset-env
使用caller (opens new window) 数据来确定是否import()
应转换 ES 模块和模块功能(例如)。通常,caller
数据将在捆绑器插件中指定(例如babel-loader
,@rollup/plugin-babel
),因此不建议caller
您自己传递数据——传递的数据caller
可能会覆盖来自捆绑器插件的数据,如果捆绑器支持新模块功能,将来您可能会得到次优结果。
# debug
(opens new window)
boolean
, 默认为false
.
输出到console.log
polyfills 和转换插件preset-env
,如果适用的话,你的哪个目标需要它。
# include
(opens new window)
Array<string|RegExp>
, 默认为[]
.
版本 | 变化 |
---|---|
v7.4.0 | 支持注入core-js@3 polyfill |
始终包含的一系列插件。
有效选项包括:
Babel 插件
——全名和简写名都被支持,例如下面的插件在功能上是等价的:@babel/plugin-transform-spread
@babel/transform-spread
babel-transform-spread
transform-spread
内置插件(适用于core-js@2 (opens new window) 和core-js@3 (opens new window) ,例如
es.map
,es.set
, 或es.object.assign
.
插件名称可以完全或部分指定(或使用RegExp
)。
可接受的输入:
- 全名 ( *
string
):"es.math.sign"
- 部分名称(*
string
):("es.math.*"
解析为所有带es.math
前缀的插件) RegExp
对象:/^transform-.*$/
或new RegExp("^transform-modules-.*")
请注意,上面的内容.
相当于RegExp
匹配任何字符,而不是实际'.'
字符。另请注意,匹配任何字符.*
用于格式RegExp
而不是*
格式glob
。
如果本机实现中存在错误,或者不受支持的功能 + 受支持的功能的组合不起作用,则此选项很有用。
例如,Node 4 支持原生类但不支持传播。如果super
与 spread 参数一起使用,则@babel/plugin-transform-classes
转换需要为include
d,因为不可能用super
其他方式转换 spread。
注意:
include
和exclude
选项仅适用于此预设中包含的插件 (opens new window) ;因此,例如,包含@babel/plugin-proposal-do-expressions
或排除@babel/plugin-proposal-function-bind
将引发错误。要使用此预设中未包含的插件,请将它们直接添加到您的“插件” (opens new window) 中。
# exclude
(opens new window)
Array<string|RegExp>
, 默认为[]
.
始终排除/删除的一组插件。
可能的选项与选项相同include
。
@babel/plugin-transform-regenerator
如果您不使用生成器并且不想包含regeneratorRuntime
(使用时useBuiltIns
)或使用其他插件(如fast-async (opens new window) 而不是Babel 的 async-to-gen ) (opens new window) ,则此选项对于排除转换很有用。
# useBuiltIns
(opens new window)
"usage"
| "entry"
| false
, 默认为false
.
此选项配置如何@babel/preset-env
处理 polyfill。
当使用usage
或选项时,将添加对模块的直接引用作为裸导入(或需要)。这意味着将相对于文件本身进行解析,并且需要可访问。entry``@babel/preset-env``core-js``core-js
由于@babel/polyfill
在 7.4.0 中已弃用,我们建议直接core-js
通过选项添加和设置版本corejs (opens new window) 。
- npm
npm install core-js@3 --save# ornpm install core-js@2 --save
- yarn
yarn add core-js@3
# or
yarn add core-js@2
# useBuiltIns: 'entry'
(opens new window)
版本 | 变化 |
---|---|
v7.4.0 | 支持注入core-js@3 polyfill |
import "core-js";
注意:在整个应用程序中只使用一次。如果您正在使用@babel/polyfill
,它已经包含core-js
:导入它两次将引发错误。多次导入或需要这些包可能会导致全局冲突和其他难以追踪的问题。我们建议创建仅包含语句的单个条目文件import
。
此选项启用一个新插件,该插件根据环境将import "core-js/stable";
andrequire("core-js");
语句替换为对不同入口点的单独导入。core-js
在
JavaScript
import "core-js";
Out(因环境而异)
JavaScript
import "core-js/modules/es.string.pad-start";
import "core-js/modules/es.string.pad-end";
为每个可能的 ECMAScript 特性导入加载"core-js"
polyfill:如果你知道你只需要其中的一些呢?使用 时core-js@3
,@babel/preset-env
能够优化每个core-js
入口点及其组合。例如,您可能只想填充数组方法和新Math
提案:
在
JavaScript
import "core-js/es/array";
import "core-js/proposals/math-extensions";
Out(因环境而异)
JavaScript
import "core-js/modules/es.array.unscopables.flat";
import "core-js/modules/es.array.unscopables.flat-map";
import "core-js/modules/esnext.math.clamp";
import "core-js/modules/esnext.math.deg-per-rad";
import "core-js/modules/esnext.math.degrees";
import "core-js/modules/esnext.math.fscale";
import "core-js/modules/esnext.math.rad-per-deg";
import "core-js/modules/esnext.math.radians";
import "core-js/modules/esnext.math.scale";
您可以阅读core-js (opens new window) 的文档以获取有关不同入口点的更多信息。
注意:使用时
core-js@2
(显式使用corejs: "2" (opens new window) 选项或隐式使用),@babel/preset-env
还将转换@babel/polyfill
. 此行为已弃用,因为它无法@babel/polyfill
与不同core-js
版本一起使用。
# useBuiltIns: 'usage'
(opens new window)
在每个文件中使用 polyfills 时添加特定的导入。我们利用了打包器只会加载同一个 polyfill 一次这一事实。
在
一个.js
var a = new Promise();
b.js
var b = new Map();
Out(如果环境不支持)
一个.js
import "core-js/modules/es.promise";
var a = new Promise();
b.js
import "core-js/modules/es.map";
var b = new Map();
Out(如果环境支持)
一个.js
var a = new Promise();
b.js
var b = new Map();
# useBuiltIns: false
(opens new window)
不要为每个文件自动添加 polyfill,也不要将import "core-js"
or转换import "@babel/polyfill"
为单个 polyfill。
# corejs
(opens new window)
添加于:v7.4.0
string
或者{ version: string, proposals: boolean }
, 默认为"2.0"
. 该version
字符串可以是任何受支持的core-js
版本。例如,"3.8"
或"2.0"
。
useBuiltIns: usage
此选项仅在与or一起使用时有效useBuiltIns: entry
,并确保@babel/preset-env
注入您的版本支持的 polyfill core-js
。建议指定次要版本,否则"3"
将被解释为"3.0"
可能不包含最新功能的 polyfill。
默认情况下,只会注入用于稳定 ECMAScript 特性的 polyfill:如果你想 polyfill 提案,你有三种不同的选择:
- 使用时* ,*
useBuiltIns: "entry"
可以直接导入一个proposal polyfill (opens new window) :。import "core-js/proposals/string-replace-all"
- 使用时*
useBuiltIns: "usage"
你有两种不同的选择: - 将*
shippedProposals
选项设置为true
。这将为已经在浏览器中发布了一段时间的提案启用 polyfills 和 transforms。 - 使用*
corejs: { version: "3.8", proposals: true }
。这将使core-js@3.8
.
# forceAllTransforms
(opens new window)
boolean
, 默认为false
.
例子借助 Babel 7 的JavaScript 配置文件支持,如果 env 设置为``.
babel.config.js
注意:
targets.uglify
已弃用并将在下一个专业中删除以支持这一点。
默认情况下,此预设将运行目标环境所需的所有转换。如果您想强制运行所有转换,请启用此选项,如果输出将通过 UglifyJS 或仅支持 ES5 的环境运行,这将很有用。
注意:如果您需要一个支持 ES6 语法的替代压缩器,我们推荐Terser (opens new window) 。
# configPath
(opens new window)
string
, 默认为process.cwd()
配置搜索 browserslist 的起点,并上升到系统根目录,直到找到为止。
# ignoreBrowserslistConfig
(opens new window)
boolean
, 默认为false
切换是否使用browserslist 配置源 (opens new window) ,包括搜索任何 browserslist 文件或引用 package.json 中的 browserslist 键。这对于使用 browserslist 配置文件的项目很有用,这些文件不会用 Babel 编译。
# browserslistEnv
(opens new window)
添加于:v7.10.0``string
,默认为undefined
要使用的Browserslist环境
。
# shippedProposals
(opens new window)
boolean
, 默认为false
版本 | 变化 |
---|---|
v7.14.0 | 包括私人领域品牌检查 |
v7.12.0 | 包含类静态块和导入断言 |
v7.10.0 | 包括类属性和私有方法 |
v7.9.0 | 包括数字分隔符 |
切换启用对已在浏览器中发布的内置/功能建议的支持。如果你的目标环境对一个特性提议有原生支持,它匹配的解析器语法插件将被启用而不是执行任何转换。请注意,这不会启用与 相同的转换@babel/preset-stage-3 (opens new window) ,因为提案可以在登陆浏览器之前继续更改。
目前支持以下内容:
使用时注入的内置函数useBuiltIns: "usage"
esnext.global-this
(仅支持core-js@3
)esnext.string.match-all
(仅 支持core-js@3
)
特征
类静态块
导入断言
(仅解析)私人领域品牌检查
Materialized Features这些特性shippedProposals
在旧的 Babel 版本中是落后的。它们现在普遍可用。
类属性
数字分隔符
私有方法
您可以在此处
阅读有关配置预设选项的更多信息
# 注意事项
# 无效的浏览器列表查询 (opens new window)
虽然op_mini all
是一个有效的浏览器列表查询,但由于缺少 (opens new window) 对 Opera Mini 的支持数据,preset-env 目前会忽略它。