跳至主要内容

@babel/preset-env

@babel/preset-env 是一个智能预设,允许您使用最新的 JavaScript,而无需微观管理目标环境所需的语法转换(以及可选的浏览器 polyfill)。这既可以让您的生活更轻松,又能使 JavaScript 包更小!

安装

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

工作原理

如果没有许多很棒的开源项目,如 browserslistcompat-tableelectron-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 文件来指定目标。您可能已经拥有此配置文件,因为它被生态系统中的许多工具使用,例如 autoprefixerstylelinteslint-plugin-compat 等等。

默认情况下,@babel/preset-env 将使用 browserslist 配置源除非 设置了 targetsignoreBrowserslistConfig 选项。

提示

如果您依赖 browserslist 的默认查询(显式或没有 browserslist 配置),您需要查看 无目标 部分,了解 preset-env 的行为。

例如,仅包含浏览器市场份额 >0.25% 的用户所需的 polyfill 和代码转换(忽略没有安全更新的浏览器,如 IE 10 和 BlackBerry)

babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry",
"corejs": "3.22"
}
]
]
}
.browserslistrc
> 0.25%
not dead

package.json
{ "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-envtargets 选项指定的浏览器支持目标启用或禁用每个组。

启用此选项后,@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@2core-js@3,例如 es.mapes.setes.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 转译扩展运算符。

注意

includeexclude 选项适用于此预设包含的插件;因此,例如,包含 @babel/plugin-proposal-do-expressions 或排除 @babel/plugin-proposal-function-bind 将会引发错误。要使用此预设包含的插件,请将其直接添加到您的"plugins"中。

exclude

Array<string|RegExp>,默认为 []

要始终排除/删除的插件数组。

可能的选项与 include 选项相同。

此选项对于排除像 @babel/plugin-transform-regenerator 这样的转换很有用,例如,如果您使用的是像 fast-async 而不是 Babel 的 async-to-gen 这样的其他插件。

useBuiltIns

"usage" | "entry" | false,默认为 false

此选项配置 @babel/preset-env 如何处理 polyfill。

当使用 usageentry 选项时,@babel/preset-env 会将对 core-js 模块的直接引用添加为裸导入(或 require)。这意味着 core-js 将相对于文件本身进行解析,并且需要是可访问的。

由于 @babel/polyfill 在 7.4.0 中已弃用,我们建议直接添加 core-js 并通过corejs 选项设置版本。

npm install core-js@3 --save

# or

npm install core-js@2 --save

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 入口点的单独导入。

输入

JavaScript
import "core-js";

输出(根据环境而异)

JavaScript
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

输入

JavaScript
import "core-js/es/array";
import "core-js/proposals/math-extensions";

输出(根据环境而异)

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 的文档以获取有关不同入口点的更多信息。

注意

当使用 core-js@2 时(显式使用corejs: "2" 选项或隐式使用),@babel/preset-env 也会转换 @babel/polyfill 的导入和 require。不建议使用此行为,因为无法将 @babel/polyfill 与不同的 core-js 版本一起使用。

useBuiltIns: 'usage'

在每个文件中使用 polyfill 时添加特定的导入。我们利用了捆绑器只会加载一次相同 polyfill 的事实。

输入

a.js
var a = new Promise();
b.js
var b = new Map();

输出(如果环境不支持)

a.js
import "core-js/modules/es.promise";
var a = new Promise();
b.js
import "core-js/modules/es.map";
var b = new Map();

输出(如果环境支持)

a.js
var a = new Promise();
b.js
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: usageuseBuiltIns: entry 一起使用时才有效,并确保 @babel/preset-env 注入您的 core-js 版本支持的 polyfill。建议指定次要版本,否则 "3" 将被解释为 "3.0",这可能不包括对最新功能的 polyfill。

默认情况下,仅注入稳定 ECMAScript 功能的 polyfill:如果您想对提案进行 polyfill,您有三种不同的选择

  • 当使用 useBuiltIns: "entry" 时,您可以直接导入提案 polyfillimport "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,则可以强制运行所有转换。

babel.config.js
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" 时注入的内置组件

特征

已实现的特征 这些特征在旧版 Babel 中位于 shippedProposals 标志之后。它们现在普遍可用。

您可以在此处阅读有关配置预设选项的更多信息

注意事项

无效的 browserslist 查询

虽然 op_mini all 是有效的 browserslist 查询,但由于缺少对 Opera Mini 的支持数据,preset-env 当前会忽略它。