@babel/preset-env
@babel/preset-env
是一个智能预设,允许您使用最新的 JavaScript,而无需微观管理目标环境所需的语法转换(以及可选的浏览器 polyfill)。这既可以让您的生活更轻松,又能使 JavaScript 包更小!
安装
- npm
- Yarn
- pnpm
npm install --save-dev @babel/preset-env
yarn add --dev @babel/preset-env
pnpm add --save-dev @babel/preset-env
工作原理
如果没有许多很棒的开源项目,如 browserslist
、compat-table
和 electron-to-chromium
,@babel/preset-env
将无法实现。
我们利用这些数据源来维护 我们支持的目标环境的哪个版本 获得了对 JavaScript 语法或浏览器功能的支持的映射,以及这些语法和功能到 Babel 转换插件和 core-js polyfill 的映射。
@babel/preset-env
不会包含任何低于 Stage 3 的 JavaScript 语法提案,因为在 TC39 流程的该阶段,无论如何都不会有任何浏览器实现它。这些需要手动包含。shippedProposals
选项将包含一些浏览器已经实现的 Stage 3 提案。
@babel/preset-env
获取您指定的任何 目标环境,并根据其映射检查它们,以编译插件列表并将其传递给 Babel。
Browserslist 集成
对于基于浏览器或 Electron 的项目,我们建议使用 .browserslistrc
文件来指定目标。您可能已经拥有此配置文件,因为它被生态系统中的许多工具使用,例如 autoprefixer、stylelint、eslint-plugin-compat 等等。
默认情况下,@babel/preset-env
将使用 browserslist 配置源,除非 设置了 targets 或 ignoreBrowserslistConfig 选项。
如果您依赖 browserslist 的默认查询(显式或没有 browserslist 配置),您需要查看 无目标 部分,了解 preset-env 的行为。
例如,仅包含浏览器市场份额 >0.25% 的用户所需的 polyfill 和代码转换(忽略没有安全更新的浏览器,如 IE 10 和 BlackBerry)
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry",
"corejs": "3.22"
}
]
]
}
> 0.25%
not dead
或
{ "browserslist": "> 0.25%, not dead" }
请注意,自 v7.4.5
起,browserslist 查询使用 mobileToDesktop: true
解析。例如,如果要创建查询快照,请运行 npx browserslist --mobile-to-desktop ">0.25%, not dead"
。
选项
有关为预设设置选项的更多信息,请参阅 预设选项 文档。
targets
string | Array<string> | { [string]: string }
,默认为顶级 targets
选项(如果在 @babel/preset-env
的文档中未指定与 browserslist 相关的选项),否则默认为 {}
。
有关用法,请参阅 targets
选项 文档。
bugfixes
boolean
,默认为 false
。
添加于:v7.9.0
此选项将在 Babel 8 中默认启用。
默认情况下,@babel/preset-env
(以及一般的 Babel 插件)将 ECMAScript 语法特性分组到密切相关的较小特性集合中。这些组可能很大,并且包含许多边缘情况,例如“函数参数”包括解构、默认和剩余参数。根据此分组信息,Babel 会根据您为 @babel/preset-env
的 targets
选项指定的浏览器支持目标启用或禁用每个组。
启用此选项后,@babel/preset-env
会尝试将损坏的语法编译为目标浏览器支持的最接近的未损坏的现代语法。根据您的 targets
以及您使用的现代语法数量,这可以显着减少已编译应用程序的大小。此选项合并了 @babel/preset-modules
的功能,而无需使用其他预设。
spec
boolean
,默认为 false
。
为此预设中支持它们的任何插件启用更符合规范但可能更慢的转换。
此选项已弃用,将在 Babel 8 中删除。请考虑迁移到自 Babel 7.13 起可用的顶级 assumptions
。有关基于假设的等效配置,请参阅 “从 @babel/preset-env
的 "loose"
和 "spec"
模式迁移”,可以复制并粘贴它们作为起点。
loose
boolean
,默认为 false
。
为此预设中允许的任何插件启用 “宽松”转换。
此选项已弃用,将在 Babel 8 中删除。请考虑迁移到自 Babel 7.13 起可用的顶级 assumptions
。有关基于假设的等效配置,请参阅 “从 @babel/preset-env
的 "loose"
和 "spec"
模式迁移”,可以复制并粘贴它们作为起点。
modules
"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false
,默认为 "auto"
。
启用将 ES 模块语法转换为其他模块类型。请注意,cjs
只是 commonjs
的别名。
将其设置为 false
将保留 ES 模块。仅当您打算将原生 ES 模块发送到浏览器时才使用此选项。如果您将捆绑器与 Babel 一起使用,则始终首选默认的 modules: "auto"
。
modules: "auto"
默认情况下,@babel/preset-env
使用 caller
数据来确定是否应转换 ES 模块和模块功能(例如 import()
)。通常,caller
数据将在捆绑器插件(例如 babel-loader
、@rollup/plugin-babel
)中指定,因此不建议您自己传递 caller
数据——传递的 caller
可能会覆盖捆绑器插件中的数据,并且将来如果捆绑器支持新的模块功能,您可能会得到次优的结果。
debug
boolean
,默认为 false
。
将 preset-env
启用的 polyfill 和转换插件输出到 console.log
,以及(如果适用)需要它的目标。
include
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 和 core-js@3,例如
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
与扩展运算符参数一起使用,则需要 include
@babel/plugin-transform-classes
转换,因为否则无法使用 super
转译扩展运算符。
exclude
Array<string|RegExp>
,默认为 []
。
要始终排除/删除的插件数组。
可能的选项与 include
选项相同。
此选项对于排除像 @babel/plugin-transform-regenerator
这样的转换很有用,例如,如果您使用的是像 fast-async 而不是 Babel 的 async-to-gen 这样的其他插件。
useBuiltIns
"usage"
| "entry"
| false
,默认为 false
。
此选项配置 @babel/preset-env
如何处理 polyfill。
当使用 usage
或 entry
选项时,@babel/preset-env
会将对 core-js
模块的直接引用添加为裸导入(或 require)。这意味着 core-js
将相对于文件本身进行解析,并且需要是可访问的。
由于 @babel/polyfill
在 7.4.0 中已弃用,我们建议直接添加 core-js
并通过corejs
选项设置版本。
- npm
- Yarn
- pnpm
npm install core-js@3 --save
# or
npm install core-js@2 --save
yarn add core-js@3
# or
yarn add core-js@2
pnpm add core-js@3
# or
pnpm add core-js@2
useBuiltIns: 'entry'
历史
版本 | 更改 |
---|---|
v7.4.0 | 它替换了 "core-js/stable" 和 "regenerator-runtime/runtime" 入口导入 |
v7.0.0 | 它替换了 "@babel/polyfill" 入口导入 |
在整个应用程序中仅使用一次 import "core-js";
。
如果您正在使用 @babel/polyfill
,它已经包含了 core-js
:两次导入它将引发错误。
多次导入或 require 这些包可能会导致全局冲突和其他难以追踪的问题。我们建议创建一个仅包含 import
语句的单个入口文件。
此选项启用了一个新插件,该插件根据环境将 import "core-js/stable";
和 require("core-js");
语句替换为对不同 core-js
入口点的单独导入。
输入
import "core-js";
输出(根据环境而异)
import "core-js/modules/es.string.pad-start";
import "core-js/modules/es.string.pad-end";
导入 "core-js"
会加载所有可能的 ECMAScript 功能的 polyfill:如果您知道只需要其中一些功能怎么办?当使用 core-js@3
时,@babel/preset-env
能够优化每个 core-js
入口点及其组合。例如,您可能只想对数组方法和新的 Math
提案进行 polyfill
输入
import "core-js/es/array";
import "core-js/proposals/math-extensions";
输出(根据环境而异)
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 的文档以获取有关不同入口点的更多信息。
当使用 core-js@2
时(显式使用corejs: "2"
选项或隐式使用),@babel/preset-env
也会转换 @babel/polyfill
的导入和 require。不建议使用此行为,因为无法将 @babel/polyfill
与不同的 core-js
版本一起使用。
useBuiltIns: 'usage'
在每个文件中使用 polyfill 时添加特定的导入。我们利用了捆绑器只会加载一次相同 polyfill 的事实。
输入
var a = new Promise();
var b = new Map();
输出(如果环境不支持)
import "core-js/modules/es.promise";
var a = new Promise();
import "core-js/modules/es.map";
var b = new Map();
输出(如果环境支持)
var a = new Promise();
var b = new Map();
useBuiltIns: false
不要自动为每个文件添加 polyfill,也不要将 import "core-js"
或 import "@babel/polyfill"
转换为单独的 polyfill。
corejs
添加于:v7.4.0
string
或 { version: string, proposals: boolean }
,默认为 "2.0"
。version
字符串可以是任何受支持的 core-js
版本。例如,"3.33"
或 "2.0"
。
此选项仅在与 useBuiltIns: usage
或 useBuiltIns: entry
一起使用时才有效,并确保 @babel/preset-env
注入您的 core-js
版本支持的 polyfill。建议指定次要版本,否则 "3"
将被解释为 "3.0"
,这可能不包括对最新功能的 polyfill。
默认情况下,仅注入稳定 ECMAScript 功能的 polyfill:如果您想对提案进行 polyfill,您有三种不同的选择
- 当使用
useBuiltIns: "entry"
时,您可以直接导入提案 polyfill:import "core-js/proposals/string-replace-all"
。 - 当使用
useBuiltIns: "usage"
时,您有两种不同的选择- 将
shippedProposals
选项设置为true
。这将启用已在浏览器中发布一段时间的提案的 polyfill 和转换。 - 使用
corejs: { version: "3.8", proposals: true }
。这将启用对[email protected]
支持的每个提案的 polyfill。
- 将
forceAllTransforms
boolean
,默认为 false
。
示例
借助 Babel 7 的JavaScript 配置文件支持,如果 env 设置为 production
,则可以强制运行所有转换。
module.exports = function(api) {
return {
presets: [
[
"@babel/preset-env",
{
targets: {
chrome: 59,
edge: 13,
firefox: 50,
},
// for uglifyjs...
forceAllTransforms: api.env("production"),
},
],
],
};
};
targets.uglify
已弃用,并将在下一个主要版本中删除,取而代之的是此选项。
默认情况下,此预设将运行目标环境所需的所有转换。如果要强制运行所有转换,请启用此选项,如果输出将通过 UglifyJS 或仅支持 ES5 的环境运行,则此选项很有用。
如果您需要确实支持 ES6 语法的替代压缩器,我们建议使用Terser。
configPath
string
,默认为 process.cwd()
browserslist 的配置搜索将从该起点开始,并向上搜索到系统根目录,直到找到为止。
ignoreBrowserslistConfig
boolean
,默认为 false
切换是否使用browserslist 配置源,包括搜索任何 browserslist 文件或引用 package.json 中的 browserslist 键。这对于使用 browserslist 配置来处理不会使用 Babel 编译的文件的项目很有用。
browserslistEnv
添加于:v7.10.0
string
,默认为 undefined
要使用的Browserslist 环境。
shippedProposals
boolean
,默认为 false
历史
版本 | 更改 |
---|---|
v7.14.0 | 包括私有字段品牌检查 |
v7.12.0 | 包括类静态块和导入断言 |
v7.10.0 | 包括类属性和私有方法 |
v7.9.0 | 包括数字分隔符 |
切换对浏览器中已发布的内置/功能提案的支持。如果您的目标环境本身支持某个功能提案,则会启用其匹配的解析器语法插件,而不是执行任何转换。请注意,这不会启用与@babel/preset-stage-3
相同的转换,因为提案在浏览器中落地之前可能会继续更改。
当前支持以下内容
使用 useBuiltIns: "usage"
时注入的内置组件
- esnext.global-this(仅受
core-js@3
支持) - esnext.string.match-all(仅受
core-js@3
支持)
特征
已实现的特征 这些特征在旧版 Babel 中位于 shippedProposals
标志之后。它们现在普遍可用。
您可以在此处阅读有关配置预设选项的更多信息
注意事项
无效的 browserslist 查询
虽然 op_mini all
是有效的 browserslist 查询,但由于缺少对 Opera Mini 的支持数据,preset-env 当前会忽略它。