☰
Babel User Handbook 实战指南:Babel 编译工具链的安装、配置与生态集成全解析
2026/10/10 11:57:32 网站建设 项目流程
  • 文档
  • 教程

【免费下载链接】babel-handbook

:blue_book: A guided handbook on how to use Babel and how to create plugins for Babel.

项目地址:https://gitcode.com/gh_mirrors/ba/babel-handbook
点击查看免费下载

本指南以本仓库内 translations/vi/user-handbook.md(Babel User Handbook 的越南语译本)为完整骨架展开。Babel 是一个通用的 JavaScript 编译器(即 transpiler),本文将从"为什么要编译"讲起,系统覆盖 Babel 的四种接入方式(babel-cli、babel-register、babel-node、babel-core)、.babelrc与官方 Preset 配置、编译产物运行所需的 Polyfill 与 Runtime、进阶的插件细粒度控制与环境化配置,以及 Babel 与 ESLint、React、编辑器等周边工具的集成方案。读完本文,你将能够独立完成 Babel 项目的接入、编译与配置,并理解其源码到源码编译的核心原理。需要提醒的是,文中包名与命令基于文档所描述的经典工具链(示例中版本号为^6.0.0),如使用其他版本的 Babel,请以对应版本的官方文档为准。

认识 Babel:为什么需要它

JavaScript 语言本身在持续演进,新规范和新提案不断带来新特性。Babel 的核心价值在于:它可以把使用最新标准书写的 JavaScript 代码,编译成当前各种环境都能运行的版本。这一过程被称为 source-to-source compiling(源码到源码编译),也就是我们常说的 transpiling(转译)。

文档给出了最经典的例子——把 ES2015 的箭头函数:

const square = n => n * n;

转译成 ES5 的普通函数:

const square = function square(n) { return n * n; };

但这只是 Babel 能力的冰山一角:

  • 语法扩展:Babel 还支持 JSX(React 的模板语法)与 Flow(静态类型检查语法)等语法扩展;
  • 一切皆插件:Babel 中几乎所有能力都以插件(plugin)形式存在,任何人都可以利用 Babel 的完整能力编写自己的插件;
  • 核心模块化:Babel 被拆分为若干核心模块,这些模块可以被单独拿来构建"下一代 JavaScript 工具"。

理解这一点非常重要:Babel 默认不会对代码做任何转换。它是一个被广泛复用、用途各异的通用编译器,你必须显式告诉它"要做什么"——通过安装插件(plugins)或Preset(预设,即一组插件的集合)来下达指令。

安装与运行 Babel:四种官方接入方式

由于 JavaScript 社区没有统一的构建工具,Babel 为各大主流工具链都提供了官方集成(从 Gulp 到 Browserify,从 Ember 到 Meteor)。本文只覆盖 Babel 内置的四种接入方式,它们适用于不同场景。

前置要求:下文命令依赖node与npm,请确保你已熟悉这两个命令行工具。

babel-cli:命令行编译

Babel 的 CLI 是从命令行编译文件最简单的方式。先全局安装以学习基本用法:

$ npm install --global babel-cli

编译单个文件:

$ babel my-file.js

默认情况下,编译结果会直接打印到终端。如果要写入文件,使用--out-file或它的简写-o:

$ babel example.js --out-file compiled.js # 或 $ babel example.js -o compiled.js

如果要编译整个目录到新目录,使用--out-dir或简写-d:

$ babel src --out-dir lib # 或 $ babel src -d lib

在项目内运行 Babel CLI

虽然可以全局安装 Babel CLI,但更推荐在每个项目内本地安装,原因有两个:

  1. 同一台机器上的不同项目可以依赖不同版本的 Babel,从而逐个升级互不影响;
  2. 项目不再隐式依赖所在环境,可移植性更强、更易搭建。

本地安装:

$ npm install --save-dev babel-cli

注:全局运行 Babel 通常不是好主意,可以通过npm uninstall --global babel-cli卸载全局副本。

安装完成后,package.json应包含如下内容:

{ "name": "my-project", "version": "1.0.0", "devDependencies": { "babel-cli": "^6.0.0" } }

接着,把命令写进npm scripts,让脚本使用本地版本而不是直接调用命令行。为package.json添加"scripts"字段,并把 Babel 命令作为build任务:

{ "name": "my-project", "version": "1.0.0", + "scripts": { + "build": "babel src -d lib" + }, "devDependencies": { "babel-cli": "^6.0.0" } }

然后从终端运行:

$ npm run build

效果与之前一致,区别在于现在使用的是项目内的本地副本。

babel-register:通过 require 即时编译

第二种常见方式是通过babel-register:只需require文件即可触发 Babel 编译,与现有项目结构集成度更高。

注意:babel-register不适合生产环境。以这种方式编译后部署被视为不良实践,更好的做法是部署前预先编译完成。但它非常适合本地运行的构建脚本等场景。

首先在项目中创建index.js:

console.log("Hello world!");

直接运行node index.js不会经过 Babel 编译,因此我们改用babel-register。先安装:

$ npm install --save-dev babel-register

再创建register.js:

require("babel-register"); require("./index.js");

这段代码的作用是把 Babel注册进 Node 的模块系统,此后所有被require的文件都会先经过 Babel 编译。

现在用register.js代替node index.js:

$ node register.js

注意:不能在你希望被编译的同一个文件里注册 Babel,因为 Node 执行该文件时 Babel 还没来得及编译它:

require("babel-register"); // 不会编译: console.log("Hello world!");

babel-node:node 的直接替代品

如果只是通过nodeCLI 运行一些代码,最简单的集成方式是用babel-nodeCLI——它基本是nodeCLI 的即插即用替代品。

注意:同样不适合生产环境,理由与babel-register一致;但非常适合本地构建脚本。

先确保安装了babel-cli:

$ npm install --save-dev babel-cli

关于为何要本地安装,可回顾上文 在项目内运行 Babel CLI 一节。

然后把所有运行node的地方替换为babel-node。如果使用 npmscripts,只需:

{ "scripts": { - "script-name": "node script.js" + "script-name": "babel-node script.js" } }

否则需要写出babel-node的完整路径:

- node script.js + ./node_modules/.bin/babel-node script.js

提示:也可以借助npm-run这类工具来简化本地二进制调用。

babel-core:以编程方式调用 Babel

如果你需要在代码中程序化地使用 Babel,可以直接使用babel-core包。先安装:

$ npm install babel-core
var babel = require("babel-core");

如果有一段 JavaScript 字符串,可直接用babel.transform编译:

babel.transform("code();", options); // => { code, map, ast }

如果处理的是文件,可以使用异步 API:

babel.transformFile("filename.js", options, function(err, result) { result; // => { code, map, ast } });

或同步 API:

babel.transformFileSync("filename.js", options); // => { code, map, ast }

如果你手中已经有一个 Babel 的 AST(抽象语法树),也可以直接从 AST 转换:

babel.transformFromAst(ast, code, options); // => { code, map, ast }

以上所有方法都会返回{ code, map, ast }三件套:code是编译后的代码字符串,map是 source map(便于调试时映射回源码),ast是转换后的抽象语法树。其中transformFromAst的存在也印证了 Babel 的流水线本质:解析(parse)→ 遍历与转换(transform)→ 生成(generate),任何一环都可以被单独接管。关于 AST 与各核心模块(babylon、babel-traverse、babel-types、babel-generator等)的深入内容,可参考本仓库的姊妹篇 Babel Plugin Handbook。

配置 Babel:.babelrc与官方 Preset

你可能已经注意到:单独运行 Babel 时,它似乎只是把 JS 文件从一个位置复制到另一个位置,什么都没做。原因正如前文所说——Babel 默认不做任何事,必须通过安装插件或 Preset 来明确指示行为。

.babelrc配置文件

首先需要在项目根目录创建.babelrc配置文件,初始内容如下:

{ "presets": [], "plugins": [] }

这个文件就是你配置 Babel 行为的入口。

注:虽然也可以通过其他方式向 Babel 传参,但.babelrc是社区约定俗成、也是最推荐的配置方式。

babel-preset-es2015:编译 ES2015

先让 Babel 把 ES2015(最新版 JavaScript 标准,即 ES6)编译成 ES5(当时绝大多数环境可用的版本)。安装 "es2015" Preset:

$ npm install --save-dev babel-preset-es2015

然后修改.babelrc,加入该 Preset:

{ "presets": [ + "es2015" ], "plugins": [] }

babel-preset-react:支持 JSX 与 React

接入 React 同样简单。安装 Preset:

$ npm install --save-dev babel-preset-react

然后把它加入.babelrc:

{ "presets": [ "es2015", + "react" ], "plugins": [] }

babel-preset-stage-x:TC39 提案阶段

JavaScript 中还有一些正在进入标准的提案,它们经由 TC39(负责 ECMAScript 标准的技术委员会)流程推进。该流程分为 5 个阶段(0–4):提案获得的关注越多、越可能被纳入标准,就会逐级前进,最终在阶段 4 被正式纳入标准。

这些提案在 Babel 中以 4 个 Preset 打包提供:

  • babel-preset-stage-0
  • babel-preset-stage-1
  • babel-preset-stage-2
  • babel-preset-stage-3

注意:不存在 stage-4 Preset,因为阶段 4 的提案就是上面提到的es2015Preset 所覆盖的内容。

这些 Preset 之间存在依赖链:babel-preset-stage-1依赖babel-preset-stage-2,而babel-preset-stage-2又依赖babel-preset-stage-3(即后阶段 Preset 自动包含更早期提案的转换能力,安装一个即可获得完整链路)。

按需安装感兴趣的阶段:

$ npm install --save-dev babel-preset-stage-2

然后加入.babelrc:

{ "presets": [ "es2015", "react", + "stage-2" ], "plugins": [] }

运行 Babel 生成的代码:Polyfill 与 Runtime

代码编译完成并不意味着大功告成——编译后的代码在目标环境中能否真正运行,是另一个问题。

babel-polyfill:补齐缺失的 API

几乎所有的"未来语法"都可以被 Babel 编译,但API 不行。语法可以转译,运行时缺失的内建方法却无法靠转译凭空造出来。

文档给出了一个典型例子。下面的代码含有一个需要编译的箭头函数:

function addAll() { return Array.from(arguments).reduce((a, b) => a + b); }

编译后变成:

function addAll() { return Array.from(arguments).reduce(function(a, b) { return a + b; }); }

然而它在某些环境仍然无法运行,因为Array.from并非在所有 JavaScript 环境中都存在:

Uncaught TypeError: Array.from is not a function

解决这个问题需要用到Polyfill(垫片)。简单说,polyfill 是一段模拟当前运行时中不存在之原生 API 的代码,让你能在Array.from等 API 正式普及之前就使用它们。

Babel 使用优秀的 core-js 作为其 polyfill 基础,并配合定制化的 regenerator runtime 来让 generator 和 async 函数正常工作。

引入方式:先用 npm 安装:

$ npm install --save babel-polyfill

然后在任何需要它的文件顶部引入:

import "babel-polyfill";

注意安装参数是--save(运行时依赖),因为 polyfill 是随应用运行的代码,而不是构建期工具。

babel-runtime:抽取公共 helper 代码

为了按 ECMAScript 规范实现某些细节,Babel 会使用一些 "helper" 方法以保证生成代码的整洁。这些 helper 通常较长,且会被追加到每个文件的顶部,造成大量重复。解决办法是把它们集中到一个统一的 "runtime" 中,通过require按需引入。

先安装babel-plugin-transform-runtime(构建期插件)和babel-runtime(运行时依赖):

$ npm install --save-dev babel-plugin-transform-runtime $ npm install --save babel-runtime

然后更新.babelrc:

{ "plugins": [ + "transform-runtime", "transform-es2015-classes" ] }

现在 Babel 会把如下代码:

class Foo { method() {} }

编译成:

import _classCallCheck from "babel-runtime/helpers/classCallCheck"; import _createClass from "babel-runtime/helpers/createClass"; let Foo = function () { function Foo() { _classCallCheck(this, Foo); } _createClass(Foo, [{ key: "method", value: function method() {} }]); return Foo; }();

而不是把_classCallCheck、_createClass这些 helper 复制进每一个需要它们的文件——这正是babel-runtime与babel-polyfill的分工差异:前者管"编译期抽出的 helper 共享",后者管"运行时缺失 API 的补齐"。

进阶配置:细粒度控制

对大多数项目而言,使用内置 Preset 就够了。但 Babel 暴露了远比这精细的控制能力。

手动指定插件

Preset 本质上就是一组预先配置好的插件集合。如果你想自定义组合,可以手动指定插件,用法与 Preset 几乎一致。

先安装插件:

$ npm install --save-dev babel-plugin-transform-es2015-classes

再把plugins字段加入.babelrc:

{ + "plugins": [ + "transform-es2015-classes" + ] }

这让你对具体执行的转换拥有更细粒度的控制。官方插件的完整列表、以及社区构建的各类babel-plugin-*包,都是值得检索的资源;如果你希望学习如何编写自己的插件,请阅读本仓库的 Babel Plugin Handbook。

插件选项(Plugin Options)

许多插件还提供选项以改变行为。例如,大量转换插件都有 "loose" 模式:以牺牲部分规范行为为代价,换取更简单、性能更好的生成代码。

给插件添加选项只需把字符串形式的插件名改为数组形式:

{ "plugins": [ - "transform-es2015-classes" + ["transform-es2015-classes", { "loose": true }] ] }

数组的第一个元素是插件名,第二个元素是选项对象。loose: true是最常见的一个选项,此外不同插件还有各自的专属选项,具体以对应插件文档为准。

基于环境定制配置(env)

Babel 插件解决的问题多种多样:很多是辅助调试或对接工具的开发期插件,也有很多是用于生产环境代码优化的插件。因此,按环境切换 Babel 配置是常见需求,.babelrc原生支持:

{ "presets": ["es2015"], "plugins": [], + "env": { + "development": { + "plugins": [...] + }, + "production": { + "plugins": [...] + } } }

Babel 会根据当前环境启用env中对应的配置。环境判定顺序如下:

  1. 优先使用process.env.BABEL_ENV;
  2. 若BABEL_ENV不可用,回退到NODE_ENV;
  3. 若两者都不可用,默认值取"development"。

在命令行中设置环境变量的方式因平台而异:

Unix

$ BABEL_ENV=production [COMMAND] $ NODE_ENV=production [COMMAND]

Windows

$ SET BABEL_ENV=production $ [COMMAND]

注:[COMMAND]指你运行 Babel 所使用的任意命令(如babel、babel-node,若使用 register 钩子也可能是node)。

提示:如果希望命令在 Unix 和 Windows 上都可运行,可以借助cross-env这类工具跨平台地设置环境变量。

制作自己的 Preset

手动指定插件、插件选项、按环境配置……所有这些配置如果要在每个项目中重复书写,显然是巨大的重复劳动。为此,社区被鼓励创建自己的 Preset——可以是为特定 Node 版本定制的 Preset,也可以是覆盖整个公司规范的 Preset。

创建 Preset 很容易。假设你有这样一份.babelrc:

{ "presets": [ "es2015", "react" ], "plugins": [ "transform-flow-strip-types" ] }

你只需创建一个遵循babel-preset-*命名规范的新项目(请对babel-preset-命名空间保持责任感),并创建两个文件。

第一个是package.json,声明 Preset 所需的dependencies:

{ "name": "babel-preset-my-awesome-preset", "version": "1.0.0", "author": "James Kyle <me@thejameskyle.com>", "dependencies": { "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.3.13", "babel-plugin-transform-flow-strip-types": "^6.3.15" } }

第二个是index.js,把.babelrc的内容导出,并将插件/Preset 字符串替换为require调用:

module.exports = { presets: [ require("babel-preset-es2015"), require("babel-preset-react") ], plugins: [ require("babel-plugin-transform-flow-strip-types") ] };

最后发布到 npm,就能像使用任何内置 Preset 一样使用它了。

Babel 与周边工具生态

Babel 本身配置起来并不复杂,但如何与其他工具协同,往往是新手最困惑的地方。Babel 团队与众多项目保持紧密合作,以尽量降低集成难度。

静态分析:ESLint +babel-eslint

新标准为语言带来大量新语法,静态分析工具也在逐步跟进。ESLint 是最流行的 lint 工具之一,Babel 官方维护了babel-eslint集成。

安装eslint和babel-eslint:

$ npm install --save-dev eslint babel-eslint

在项目现有的.eslintrc中把parser设为babel-eslint:

{ + "parser": "babel-eslint", "rules": { ... } }

再往 npmpackage.jsonscripts 中添加lint任务:

{ "name": "my-module", "scripts": { + "lint": "eslint my-files.js" }, "devDependencies": { "babel-eslint": "...", "eslint": "..." } }

然后运行任务即可:

$ npm run lint

更多细节可查阅babel-eslint与eslint各自的官方文档。

代码风格检查(Code Style)

注:JSCS 已并入 ESLint,因此代码风格检查也可以直接使用 ESLint 实现。

JSCS 曾是把 lint 推进到"检查代码风格本身"的流行工具,Babel 与 JSCS 两个项目的核心维护者提供了官方集成。更棒的是,该集成后来直接内置于 JSCS 的--esnext选项中,因此接入 Babel 只需一行:

$ jscs . --esnext

或者在.jscsrc文件中加上esnext选项:

{ "preset": "airbnb", + "esnext": true }

文档生成(Documentation)

借助 Babel、ES2015 与 Flow,你可以从代码中推断出大量信息。使用documentation.js可以非常轻松地生成详尽的 API 文档——它在幕后正是利用 Babel 来支持包括 Flow 类型注解在内的最新语法,从而在文档中声明代码中的类型。

框架集成:React 与 JSX

各大主流 JavaScript 框架都在围绕语言的未来调整 API,这带来大量工具链投入。框架不仅可以使用 Babel,还能以扩展 Babel 的方式改善用户体验。

React 是典型代表:它大幅调整 API 以对齐 ES2015 的 class 写法,并且依赖 Babel 来编译其 JSX 语法,逐步废弃了自己的定制工具链。你可以按照前文 babel-preset-react 一节的步骤直接开始。

React 社区还基于 Babel 构建了众多转换插件,其中最具代表性的是babel-plugin-react-transform,它与一系列 React 专属 transform 组合,可以实现hot module reloading(热模块替换)以及其他调试工具。

文本编辑器与 IDE

引入 ES2015、JSX 和 Flow 语法后,如果编辑器不支持这些语法,开发体验会非常糟糕。为此,主流编辑器都有对应的 Babel 插件可供配置:

  • Sublime Text
  • Atom
  • Vim
  • WebStorm

获取支持:社区渠道与高质量 Bug 报告

Babel 拥有庞大且快速增长的社区。在所有社区渠道中,都执行着一份行为准则(Code of Conduct),违反准则会招致相应处理,因此与他人交流时请遵守并保持自律。同时,社区也在培养"自助互助"文化:如果看到自己会解答的问题,花几分钟帮一把,并尽量保持友善与理解。

官方支持渠道主要包括:

  • Babel Forum:基于 Discourse 论坛软件托管的讨论社区,适合发帖提问;
  • Babel Chat:Slack 频道,适合寻求即时帮助;
  • Babel Issues:使用 GitHub Issue 跟踪器管理,可查看全部打开/关闭的 issue,也可以新建 bug 报告或功能请求。

如何撰写一份高质量的 Bug 报告

Babel 的问题有时很难远程调试,所以高质量的 bug 报告能显著加快问题解决速度。第一步永远是隔离问题:你的整套环境配置几乎不可能都是问题来源;如果问题出在某段输入代码上,就尽可能删减代码,直到得到一份"仍能复现问题的最小样本"。带着最小复现样本去提问,维护者才能快速定位并修复。

本手册在仓库中的位置

本指南的原始素材位于本仓库的 translations/vi/user-handbook.md,它是 Babel User Handbook 的越南语译本;英文原文(作为翻译基准的 master 版本)位于 translations/en/user-handbook.md。整个仓库围绕《Babel Handbook》组织,分为两大部分:本指南所属的User Handbook(如何安装、配置和使用 Babel),以及Plugin Handbook(如何为 Babel 编写插件,见 translations/vi/plugin-handbook.md)。多语言翻译通过 crowdin.yaml 配置的 Crowdin 项目协作完成,具体贡献流程见 CONTRIBUTING.md;仓库元信息(项目名babel-handbook、许可证cc-by-4.0等)可在 package.json 中查看。

回到本文的主题脉络:安装接入 → 配置 Preset → 处理编译产物运行 → 细粒度进阶控制 → 生态工具协同,这就是一份完整的 Babel 使用闭环。从babel-cli的第一条命令开始,到自定义 Preset 发布 npm 结束,你可以把这份指南当作项目接入 Babel 时的逐节对照手册;而当你想更进一步、亲手编写属于自己的 Babel 转换插件时,直接翻开仓库中的 Plugin Handbook 即可无缝衔接。

  • 文档
  • 教程

【免费下载链接】babel-handbook

:blue_book: A guided handbook on how to use Babel and how to create plugins for Babel.

项目地址:https://gitcode.com/gh_mirrors/ba/babel-handbook
点击查看免费下载
上一篇:Finagle Random Aperture 负载均衡:用二项分布量化随机孔径的负载分带效应
下一篇:GitHub中文化:5分钟把GitHub界面变成中文,新手也能一次搞定

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询