使用指南
Babel 工具链中有很多工具,无论您是“最终用户”还是构建 Babel 本身的集成,这些工具都试图让您更轻松地使用 Babel。这将简要介绍这些工具,您可以在文档的“使用”部分中阅读有关它们的更多信息。
如果您正在使用框架,则配置 Babel 的工作可能会有所不同,或者实际上已经为您处理好了。请查看我们的交互式设置指南。
概述
本指南将向您展示如何将使用 ES2015+ 语法的 JavaScript 应用程序代码编译为可在当前浏览器中运行的代码。这将涉及转换新语法和填充缺失的功能。
设置此过程的整个过程涉及
-
运行以下命令以安装软件包
- npm
- Yarn
- pnpm
npm install --save-dev @babel/core @babel/cli @babel/preset-env
yarn add --dev @babel/core @babel/cli @babel/preset-env
pnpm add --save-dev @babel/core @babel/cli @babel/preset-env
-
在项目的根目录下创建一个名为
babel.config.json
(需要v7.8.0
及更高版本)的配置文件,其内容如下babel.config.json{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
]
]
}上面的浏览器列表只是一个任意示例。您必须根据要支持的浏览器对其进行调整。有关更多
@babel/preset-env
选项,请参阅此处。
或者,如果您使用的是旧版 Babel,则使用 babel.config.js
const presets = [
[
"@babel/preset-env",
{
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1",
},
useBuiltIns: "usage",
corejs: "3.6.4",
},
],
];
module.exports = { presets };
-
并运行以下命令将所有代码从
src
目录编译到lib
Shell./node_modules/.bin/babel src --out-dir lib
您可以使用 [email protected] 附带的 npm 包运行器,通过将
./node_modules/.bin/babel
替换为npx babel
来缩短该命令
继续阅读以逐步了解其工作原理以及对所用每个工具的介绍。
使用 CLI 的基本用法
您需要的所有 Babel 模块都作为单独的 npm 包发布,范围在 @babel
下(从版本 7 开始)。这种模块化设计允许各种工具,每个工具都针对特定的用例而设计。在这里,我们将看看 @babel/core
和 @babel/cli
。
核心库
Babel 的核心功能位于 @babel/core 模块中。安装后
- npm
- Yarn
- pnpm
npm install --save-dev @babel/core
yarn add --dev @babel/core
pnpm add --save-dev @babel/core
您可以在 JavaScript 程序中直接 require
它,并像这样使用它
const babel = require("@babel/core");
babel.transformSync("code", optionsObject);
但是,作为最终用户,您可能希望安装其他工具,这些工具可以作为 @babel/core
的接口,并与您的开发过程很好地集成。即便如此,您可能仍然希望查看其文档页面以了解这些选项,其中大多数选项也可以从其他工具中设置。
CLI 工具
@babel/cli 是一个允许您从终端使用 babel 的工具。以下是安装命令和基本用法示例
- npm
- Yarn
- pnpm
npm install --save-dev @babel/core @babel/cli
./node_modules/.bin/babel src --out-dir lib
yarn add --dev @babel/core @babel/cli
./node_modules/.bin/babel src --out-dir lib
pnpm add --save-dev @babel/core @babel/cli
./node_modules/.bin/babel src --out-dir lib
这将解析 src
目录中的所有 JavaScript 文件,应用我们已告知它的任何转换,并将每个文件输出到 lib
目录。由于我们还没有告诉它应用任何转换,因此输出代码将与输入代码相同(不保留确切的代码样式)。我们可以通过将转换作为选项传递来指定我们想要的转换。
我们上面使用了 --out-dir
选项。您可以通过使用 --help
运行 cli 工具来查看它接受的其余选项。但现在对我们来说最重要的是 --plugins
和 --presets
。
插件和预设
转换以插件的形式出现,插件是小型 JavaScript 程序,用于指示 Babel 如何对代码执行转换。您甚至可以编写自己的插件,将您想要的任何转换应用于您的代码。要将 ES2015+ 语法转换为 ES5,我们可以依赖官方插件,例如 @babel/plugin-transform-arrow-functions
- npm
- Yarn
- pnpm
npm install --save-dev @babel/plugin-transform-arrow-functions
./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions
yarn add --dev @babel/plugin-transform-arrow-functions
./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions
pnpm add --save-dev @babel/plugin-transform-arrow-functions
./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions
现在,我们代码中的任何箭头函数都将转换为 ES5 兼容的函数表达式
const fn = () => 1;
// converted to
var fn = function fn() {
return 1;
};
这是一个好的开始!但是我们的代码中还有其他我们想要转换的 ES2015+ 功能。我们可以使用“预设”,它只是一组预先确定的插件,而不是一个一个地添加我们想要的所有插件。
就像插件一样,您也可以创建自己的预设来共享您需要的任何插件组合。对于我们这里的用例,有一个名为 env
的优秀预设。
- npm
- Yarn
- pnpm
npm install --save-dev @babel/preset-env
./node_modules/.bin/babel src --out-dir lib --presets=@babel/env
yarn add --dev @babel/preset-env
./node_modules/.bin/babel src --out-dir lib --presets=@babel/env
pnpm add --save-dev @babel/preset-env
./node_modules/.bin/babel src --out-dir lib --presets=@babel/env
在没有任何配置的情况下,此预设将包含所有插件以支持现代 JavaScript(ES2015、ES2016 等)。但预设也可以接受选项。让我们看看另一种传递选项的方式:配置文件,而不是从终端传递 cli 和预设选项。
配置
根据您的需要,有几种不同的方法可以使用配置文件。有关如何配置 Babel 的更多信息,请务必阅读我们的深入指南。
现在,让我们创建一个名为 babel.config.json
(需要 v7.8.0
及更高版本)的文件,其内容如下
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
}
}
]
]
}
现在,env
预设将仅加载目标浏览器中不可用的功能的转换插件。我们已经为语法做好了准备。接下来让我们看看 polyfill。
Polyfill
🚨 从 Babel 7.4.0 开始,不推荐使用此软件包,而是直接包含
core-js/stable
(用于填充 ECMAScript 功能)JavaScriptimport "core-js/stable";
如果您要将生成器或异步函数编译为 ES5,并且您使用的
@babel/core
或@babel/plugin-transform-regenerator
版本低于7.18.0
,则还必须加载regenerator 运行时
包。使用@babel/preset-env
的useBuiltIns: "usage"
选项或@babel/plugin-transform-runtime
时会自动加载它。
@babel/polyfill 模块包括 core-js 和自定义 regenerator 运行时 以模拟完整的 ES2015+ 环境。
这意味着您可以使用新的内置函数,例如 Promise
或 WeakMap
,静态方法,例如 Array.from
或 Object.assign
,实例方法,例如 Array.prototype.includes
,以及生成器函数(与 regenerator 插件一起使用时)。polyfill 添加到全局范围以及原生原型(如 String
)以实现此目的。
对于库/工具作者来说,这可能太过分了。如果您不需要像 Array.prototype.includes
这样的实例方法,则可以通过使用 transform runtime 插件而不是 @babel/polyfill
来完全避免污染全局范围。
更进一步,如果您确切知道哪些功能需要 polyfill,则可以直接从 core-js 中获取它们。
由于我们正在构建一个应用程序,因此我们可以只安装 @babel/polyfill
- npm
- Yarn
- pnpm
npm install --save @babel/polyfill
yarn add @babel/polyfill
pnpm add @babel/polyfill
请注意
--save
选项而不是--save-dev
,因为这是一个需要在源代码之前运行的 polyfill。
现在对我们来说幸运的是,我们正在使用 env
预设,它有一个 "useBuiltIns"
选项,当设置为 "usage"
时,它实际上将应用上面提到的最后一个优化,即您只包含需要的 polyfill。使用此新选项,配置更改如下
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage"
}
]
]
}
Babel 现在将检查您的所有代码中是否存在目标环境中缺少的功能,并且仅包含所需的 polyfill。例如,这段代码
Promise.resolve().finally();
将变成这样(因为 Edge 17 没有 Promise.prototype.finally
)
require("core-js/modules/es.promise.finally");
Promise.resolve().finally();
如果我们没有使用 "useBuiltIns"
选项设置为 "usage"
(默认为“false”)的 env
预设,我们将不得不仅在入口点中的任何其他代码之前需要完整的 polyfill。
例如
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "entry"
}
]
]
}
然后,首先在我们的入口文件中导入 core-js(用于填充 ECMAScript 功能)以模拟完整的 ES2015+ 环境,因为 @babel/polyfill 已被弃用
import "core-js/stable";
总结
我们使用 @babel/cli
从终端运行 Babel,使用 @babel/polyfill
来填充所有新的 JavaScript 功能,并使用 env
预设来仅包含我们使用的并且目标浏览器中缺少的功能的转换和 polyfill。
有关使用构建系统、IDE 等设置 Babel 的更多信息,请查看我们的交互式设置指南。