跳至主内容

@babel/preset-env

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

@babel/preset-env 是一个智能预设,它让你无需手动管理目标环境所需的语法转换(以及可选的浏览器 polyfill),就能使用最新的 JavaScript 语法。这既能让你的开发更轻松,又能减小 JavaScript 打包体积!

安装

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

工作原理

@babel/preset-env 的实现离不开多个优秀的开源项目,例如 browserslistcompat-tableelectron-to-chromium

我们利用这些数据源维护了支持的目标环境版本与 JavaScript 语法/浏览器特性的映射关系,以及这些语法/特性与 Babel 转换插件、core-js polyfill 的对应关系。

备注

@babel/preset-env 不会包含任何处于 TC39 流程 Stage 3 以下的 JavaScript 提案语法,因为此阶段的提案尚未被任何浏览器实现。如需使用这些语法需要手动引入。而 shippedProposals 选项会包含已被部分浏览器实现的 Stage 3 提案语法。

@babel/preset-env 会获取你指定的目标环境,并根据其内部映射关系编译出所需的插件列表,再传递给 Babel 处理。

Browserslist 集成

对于浏览器或 Electron 项目,我们推荐使用 .browserslistrc 文件来指定目标环境。你可能已经拥有此配置文件,因为它被生态中的许多工具所使用,例如 autoprefixerstylelinteslint-plugin-compat 等。

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

提示

如果你依赖 browserslist 的默认查询(显式使用或未配置 browserslist),请查看 无 targets 配置 章节了解 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 },默认值为:当未在 @babel/preset-env 文档中指定 browserslist 相关选项时使用顶层 targets 选项,否则为 {}

具体用法请参考 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 模块语法转换为其他模块类型的功能。注意 cjscommonjs 的别名。

设置为 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>,默认值为 []

History
VersionChanges
v7.4.0Support injecting core-js@3 polyfills

始终包含的插件数组。

有效选项包括:

  • Babel 插件 - 支持完整名称和简写形式,例如以下功能等价:
    • @babel/plugin-transform-spread
    • @babel/transform-spread
    • babel-transform-spread
    • transform-spread
  • 内置模块(适用于 core-js@3core-js@2,例如 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 会以裸导入(或 require)形式直接引用 core-js 模块。这意味着 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'

History
VersionChanges
v7.4.0It replaces "core-js/stable" and "regenerator-runtime/runtime" entry imports
v7.0.0It replaces "@babel/polyfill" entry imports
提示

在整个应用中仅使用一次 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 入口点及其组合。例如仅需 polyfill 数组方法和新 Math 提案:

输入

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。 此行为已弃用,因无法在不同 core-js 版本下使用 @babel/polyfill

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 版本兼容。建议指定次要版本,否则 "3" 会被解释为 "3.0" 可能不包含最新功能的垫片。

默认仅注入稳定 ECMAScript 功能的垫片。如需对提案进行垫片处理,可通过三种方式实现:

  • 使用 useBuiltIns: "entry" 时,可直接导入提案垫片import "core-js/proposals/string-replace-all"

  • 使用 useBuiltIns: "usage" 时有两种选择:

    • shippedProposals 设为 true,为已被浏览器实现的提案启用垫片和转换
    • 使用 corejs: { version: "3.8", proposals: true },启用 core-js@3.8 支持的所有提案垫片

forceAllTransforms

boolean,默认值 false

Example

With Babel 7's JavaScript config file support, you can force all transforms to be run if env is set to 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

History
VersionChanges
v7.14.0Include private field brand checks
v7.12.0Include class static block and import assertions
v7.10.0Include class properties and private methods
v7.9.0Include numeric separator

控制是否启用已被浏览器实现的提案功能。若目标环境原生支持某提案,将启用对应的语法解析插件而非执行转换。注意:这不会启用与 @babel/preset-stage-3 相同的转换逻辑,因为提案在浏览器正式支持前仍可能变更。

当前支持以下提案:

使用 useBuiltIns: "usage" 时注入的内置提案

语法特性提案

已落地的功能 这些功能在旧版 Babel 中需要启用 shippedProposals 标志。现在它们已普遍可用。

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

注意事项

无效的 browserslist 查询

尽管 op_mini all 是有效的 browserslist 查询,但由于 Opera Mini 缺乏支持数据,preset-env 目前会忽略该查询。