跳至主要内容

使用指南

Babel 工具链中有很多工具,无论您是“最终用户”还是构建 Babel 本身的集成,这些工具都试图让您更轻松地使用 Babel。这将简要介绍这些工具,您可以在文档的“使用”部分中阅读有关它们的更多信息。

如果您正在使用框架,则配置 Babel 的工作可能会有所不同,或者实际上已经为您处理好了。请查看我们的交互式设置指南

概述

本指南将向您展示如何将使用 ES2015+ 语法的 JavaScript 应用程序代码编译为可在当前浏览器中运行的代码。这将涉及转换新语法和填充缺失的功能。

设置此过程的整个过程涉及

  1. 运行以下命令以安装软件包

    npm install --save-dev @babel/core @babel/cli @babel/preset-env
  2. 在项目的根目录下创建一个名为 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

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 };
  1. 并运行以下命令将所有代码从 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 install --save-dev @babel/core

您可以在 JavaScript 程序中直接 require 它,并像这样使用它

JavaScript
const babel = require("@babel/core");

babel.transformSync("code", optionsObject);

但是,作为最终用户,您可能希望安装其他工具,这些工具可以作为 @babel/core 的接口,并与您的开发过程很好地集成。即便如此,您可能仍然希望查看其文档页面以了解这些选项,其中大多数选项也可以从其他工具中设置。

CLI 工具

@babel/cli 是一个允许您从终端使用 babel 的工具。以下是安装命令和基本用法示例

npm install --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 install --save-dev @babel/plugin-transform-arrow-functions

./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions

现在,我们代码中的任何箭头函数都将转换为 ES5 兼容的函数表达式

JavaScript
const fn = () => 1;

// converted to

var fn = function fn() {
return 1;
};

这是一个好的开始!但是我们的代码中还有其他我们想要转换的 ES2015+ 功能。我们可以使用“预设”,它只是一组预先确定的插件,而不是一个一个地添加我们想要的所有插件。

就像插件一样,您也可以创建自己的预设来共享您需要的任何插件组合。对于我们这里的用例,有一个名为 env 的优秀预设。

npm install --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 及更高版本)的文件,其内容如下

babel.config.json
{
"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 功能)

JavaScript
import "core-js/stable";

如果您要将生成器或异步函数编译为 ES5,并且您使用的 @babel/core@babel/plugin-transform-regenerator 版本低于 7.18.0,则还必须加载 regenerator 运行时 包。使用 @babel/preset-envuseBuiltIns: "usage" 选项或 @babel/plugin-transform-runtime 时会自动加载它。

@babel/polyfill 模块包括 core-js 和自定义 regenerator 运行时 以模拟完整的 ES2015+ 环境。

这意味着您可以使用新的内置函数,例如 PromiseWeakMap,静态方法,例如 Array.fromObject.assign,实例方法,例如 Array.prototype.includes,以及生成器函数(与 regenerator 插件一起使用时)。polyfill 添加到全局范围以及原生原型(如 String)以实现此目的。

对于库/工具作者来说,这可能太过分了。如果您不需要像 Array.prototype.includes 这样的实例方法,则可以通过使用 transform runtime 插件而不是 @babel/polyfill 来完全避免污染全局范围。

更进一步,如果您确切知道哪些功能需要 polyfill,则可以直接从 core-js 中获取它们。

由于我们正在构建一个应用程序,因此我们可以只安装 @babel/polyfill

npm install --save @babel/polyfill

请注意 --save 选项而不是 --save-dev,因为这是一个需要在源代码之前运行的 polyfill。

现在对我们来说幸运的是,我们正在使用 env 预设,它有一个 "useBuiltIns" 选项,当设置为 "usage" 时,它实际上将应用上面提到的最后一个优化,即您只包含需要的 polyfill。使用此新选项,配置更改如下

babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage"
}
]
]
}

Babel 现在将检查您的所有代码中是否存在目标环境中缺少的功能,并且仅包含所需的 polyfill。例如,这段代码

JavaScript
Promise.resolve().finally();

将变成这样(因为 Edge 17 没有 Promise.prototype.finally

JavaScript
require("core-js/modules/es.promise.finally");

Promise.resolve().finally();

如果我们没有使用 "useBuiltIns" 选项设置为 "usage"(默认为“false”)的 env 预设,我们将不得不在入口点中的任何其他代码之前需要完整的 polyfill。

例如

babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "entry"
}
]
]
}

然后,首先在我们的入口文件中导入 core-js(用于填充 ECMAScript 功能)以模拟完整的 ES2015+ 环境,因为 @babel/polyfill 已被弃用

JavaScript
 import "core-js/stable";

总结

我们使用 @babel/cli 从终端运行 Babel,使用 @babel/polyfill 来填充所有新的 JavaScript 功能,并使用 env 预设来仅包含我们使用的并且目标浏览器中缺少的功能的转换和 polyfill。

有关使用构建系统、IDE 等设置 Babel 的更多信息,请查看我们的交互式设置指南