使用指南
Babel 工具链中有相当多的工具,旨在无论你是“终端用户”还是在构建 Babel 本身的集成,都能让你轻松使用 Babel。这将是对这些工具的快速介绍,你可以在文档的“使用”部分查看更多内容。
🌐 There are quite a few tools in the Babel toolchain that try to make it easy for you to use Babel whether you're an "end-user" or building an integration of Babel itself. This will be a quick introduction to those tools and you can read more about them in the "Usage" section of the docs.
如果你在使用框架,配置 Babel 的工作可能会有所不同,或者实际上已经为你处理好了。你可以查看我们的互动设置指南。
概述
🌐 Overview
本指南将向你展示如何将使用 ES2015+ 语法的 JavaScript 应用代码编译成在当前浏览器中可用的代码。这将包括转换新语法和为缺失的功能添加填充代码。
🌐 This guide will show you how to compile your JavaScript application code that uses ES2015+ syntax into code that works in current browsers. That will involve both transforming new syntax and polyfilling missing features.
设置的整个过程包括:
🌐 The entire process to set this up involves:
-
运行这些命令来安装软件包:
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/core @babel/cli @babel/preset-envyarn add --dev @babel/core @babel/cli @babel/preset-envpnpm add --save-dev @babel/core @babel/cli @babel/preset-envbun add --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
🌐 Or babel.config.js if you are using an older Babel version
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你可以使用随 npm@5.2.0 一起提供的 npm 包运行器,通过将
./node_modules/.bin/babel替换为npx babel来缩短该命令
继续阅读以了解其工作原理的分步说明以及所使用的每种工具的介绍。
🌐 Read on for a step-by-step explanation of how this works and an introduction to each of the tools used.
CLI 的基本用法
🌐 Basic usage with CLI
你需要的所有 Babel 模块都以独立的 npm 包形式发布,并归类在 @babel 下(自 7 版本起)。这种模块化设计让各种工具各自针对特定用途。在这里,我们将看看 @babel/core 和 @babel/cli。
🌐 All the Babel modules you'll need are published as separate npm packages scoped under @babel (since version 7). This modular design allows for various tools each designed for a specific use case. Here we'll look at @babel/core and @babel/cli.
核心库
🌐 Core Library
Babel 的核心功能在 @babel/core 模块里。安装它之后:
🌐 The core functionality of Babel resides at the @babel/core module. After installing it:
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/core
yarn add --dev @babel/core
pnpm add --save-dev @babel/core
bun add --dev @babel/core
你可以在你的 JavaScript 程序中直接 require 它,然后像这样使用:
🌐 you can require it directly in your JavaScript program and use it like this:
const babel = require("@babel/core");
babel.transformSync("code", optionsObject);
不过作为终端用户,你可能仍然想安装其他作为 @babel/core 接口的工具,并且能很好地与你的开发流程集成。即便如此,你可能仍然想查看它的文档页面,了解各个选项,其中大多数也可以从其他工具中设置。
🌐 As an end-user though, you'll probably want to install other tools that serve as an interface to @babel/core and integrate well with your development process. Even so, you might still want to check its documentation page to learn about the options, most of which can be set from the other tools as well.
命令行工具
🌐 CLI tool
@babel/cli 是一个可以让你在终端使用 Babel 的工具。下面是安装命令和一个基本使用示例:
- npm
- Yarn
- pnpm
- Bun
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
bun add --dev @babel/core @babel/cli
./node_modules/.bin/babel src --out-dir lib
这会解析 src 目录下的所有 JavaScript 文件,应用我们告诉它的任何转换,并将每个文件输出到 lib 目录。由于我们还没有告诉它应用任何转换,输出的代码将与输入完全相同(具体代码风格不会保留)。我们可以通过将它们作为选项传递来指定我们想要的转换。
🌐 This will parse all the JavaScript files in the src directory, apply any transformations we have told it to, and output each file to the lib directory. Since we haven't told it to apply any transformations yet, the output code will be identical to the input (exact code styling is not preserved). We can specify what transformations we want by passing them as options.
我们上面使用了 --out-dir 选项。你可以通过运行 --help 来查看 CLI 工具接受的其他选项。但现在对我们来说最重要的是 --plugins 和 --presets。
🌐 We used the --out-dir option above. You can view the rest of the options accepted by the cli tool by running it with --help. But the most important to us right now are --plugins and --presets.
插件和预设
🌐 Plugins & Presets
转换以插件的形式出现,插件是小型的 JavaScript 程序,用来告诉 Babel 如何对代码进行转换。你甚至可以自己编写插件,对代码应用任何你想要的转换。为了把 ES2015+ 语法转换成 ES5,我们可以依赖官方的插件,比如 @babel/plugin-transform-arrow-functions:
🌐 Transformations come in the form of plugins, which are small JavaScript programs that instruct Babel on how to carry out transformations to the code. You can even write your own plugins to apply any transformations you want to your code. To transform ES2015+ syntax into ES5 we can rely on official plugins like @babel/plugin-transform-arrow-functions:
- npm
- Yarn
- pnpm
- Bun
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
bun add --dev @babel/plugin-transform-arrow-functions
./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions
现在我们代码中的任何箭头函数都将转换为 ES5 兼容的函数表达式:
🌐 Now any arrow functions in our code will be transformed into ES5 compatible function expressions:
const fn = () => 1;
// converted to
var fn = function fn() {
return 1;
};
这是一个不错的开始!但我们的代码里还有其他 ES2015+ 的特性也想转换。与其一个一个地添加所有插件,我们可以使用“预设”,它就是一组预先确定好的插件集合。
🌐 That's a good start! But we also have other ES2015+ features in our code that we want transformed. Instead of adding all the plugins we want one by one, we can use a "preset" which is just a pre-determined set of plugins.
就像插件一样,你也可以创建自己的预设来分享你需要的任何插件组合。就我们这里的使用案例来说,有一个很棒的预设叫做 env。
🌐 Just like with plugins, you can create your own presets too to share any combination of plugins you need. For our use case here, there's an excellent preset named env.
- npm
- Yarn
- pnpm
- Bun
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
bun add --dev @babel/preset-env
./node_modules/.bin/babel src --out-dir lib --presets=@babel/env
没有任何配置,这个预设将包含所有插件以支持现代 JavaScript(ES2015、ES2016 等)。但预设也可以接受选项。与其从终端同时传递 CLI 和预设选项,不如看看另一种传递选项的方法:配置文件。
🌐 Without any configuration, this preset will include all plugins to support modern JavaScript (ES2015, ES2016, etc.). But presets can take options too. Rather than passing both cli and preset options from the terminal, let's look at another way of passing options: configuration files.
配置
🌐 Configuration
根据你的需求,使用配置文件的方式有几种不同的方法。务必查阅我们关于如何 配置 Babel 的详细指南,以获取更多信息。
现在,我们先创建一个名为 babel.config.json 的文件(需要 v7.8.0 及以上版本),内容如下:
🌐 For now, let's create a file called babel.config.json (requires v7.8.0 and above) with the following content:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
}
}
]
]
}
现在 env 预设只会为我们的目标浏览器中不可用的特性加载转换插件。语法部分已经准备好了。接下来我们来看看填充功能吧。
🌐 Now the env preset will only load transformation plugins for features that are not available in our target browsers. We're all set for syntax. Let's look at polyfills next.
Polyfill
🚨 As of Babel 7.4.0, this package has been deprecated in favor of directly including
core-js/stable(to polyfill ECMAScript features):JavaScriptimport "core-js/stable";If you are compiling generators or async function to ES5, and you are using a version of
@babel/coreor@babel/plugin-transform-regeneratorolder than7.18.0, you must also load theregenerator runtimepackage. It is automatically loaded when using@babel/preset-env'suseBuiltIns: "usage"option or@babel/plugin-transform-runtime.
@babel/polyfill 模块包含 core-js 和一个自定义的 regenerator runtime 来模拟完整的 ES2015+ 环境。
🌐 The @babel/polyfill module includes core-js and a custom regenerator runtime to emulate a full ES2015+ environment.
这意味着你可以使用像 Promise 或 WeakMap 这样的新内置功能,像 Array.from 或 Object.assign 这样的静态方法,像 Array.prototype.includes 这样的实例方法,以及生成器函数(在配合 regenerator 插件使用时)。这个垫片会添加到全局作用域以及像 String 这样的原生原型中来实现这些功能。
🌐 This means you can use new built-ins like Promise or WeakMap, static methods like Array.from or Object.assign, instance methods like Array.prototype.includes, and generator functions (when used alongside the regenerator plugin). The polyfill adds to the global scope as well as native prototypes like String in order to do this.
对于库/工具的作者来说,这可能有些过头。如果你不需要像 Array.prototype.includes 这样的实例方法,你完全可以不用污染全局作用域,而是使用 transform runtime 插件来替代 @babel/polyfill。
🌐 For library/tool authors this may be too much. If you don't need the instance methods like Array.prototype.includes you can do without polluting the global scope altogether by using the transform runtime plugin instead of @babel/polyfill.
更进一步,如果你确切知道哪些功能需要 polyfill,你可以直接从 core-js 引入它们。
🌐 To go one step further, if you know exactly what features you need polyfills for, you can require them directly from core-js.
既然我们正在构建一个应用,我们可以直接安装 @babel/polyfill:
🌐 Since we're building an application we can just install @babel/polyfill:
- npm
- Yarn
- pnpm
- Bun
npm install --save @babel/polyfill
yarn add @babel/polyfill
pnpm add @babel/polyfill
bun add @babel/polyfill
注意使用
--save选项而不是--save-dev,因为这是一个补丁,需要在你的源代码运行之前执行。
幸运的是,我们使用的是 env 预设,它有一个 "useBuiltIns" 选项,当设置为 "usage" 时,实际上会应用上面提到的最后一种优化,也就是只包含你需要的 polyfill。使用这个新选项后,配置会像这样更改:
🌐 Now luckily for us, we're using the env preset which has a "useBuiltIns" option that when set to "usage" will practically apply the last optimization mentioned above where you only include the polyfills you need. With this new option the configuration changes like this:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage"
}
]
]
}
Babel 现在会检查你所有的代码,看看你的目标环境缺少哪些功能,并只包含所需的 polyfill。例如这段代码:
🌐 Babel will now inspect all your code for features that are missing in your target environments and include only the required polyfills. For example this code:
Promise.resolve().finally();
会变成这样(因为 Edge 17 没有 Promise.prototype.finally):
🌐 would turn into this (because Edge 17 doesn't have Promise.prototype.finally):
require("core-js/modules/es.promise.finally");
Promise.resolve().finally();
如果我们没有使用 env 预设并且 "useBuiltIns" 选项设置为 "usage"(默认是“false”),我们就得在入口点的其他代码之前只引入一次完整的 polyfill。
🌐 If we weren't using the env preset with the "useBuiltIns" option set to "usage" (defaults to "false") we would've had to require the full polyfill only once in our entry point before any other code.
例如:
🌐 For example:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "entry"
}
]
]
}
Then import core-js (to polyfill ECMAScript features) first, in our entry file to emulate a full ES2015+ environment since @babel/polyfill has been deprecated:
import "core-js/stable";
总结
🌐 Summary
我们用 @babel/cli 从终端运行 Babel,用 @babel/polyfill 为所有新的 JavaScript 特性提供 polyfill,用 env 预设只包含我们使用且在目标浏览器中缺失的特性所需的转换和 polyfill。
🌐 We used @babel/cli to run Babel from the terminal, @babel/polyfill to polyfill all the new JavaScript features, and the env preset to only include the transformations and polyfills for the features that we use and that are missing in our target browsers.
想了解更多关于如何在你的构建系统、IDE 等中设置 Babel,请查看我们的互动安装指南。
🌐 For more information on setting up Babel with your build system, IDE, and more, check out our interactive setup guide.