文档教程【免费下载链接】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点击查看免费下载本篇技术指南以 babel-handbook 仓库中的官方《Babel 用户手册》加泰罗尼亚语版 translations/ca/user-handbook.md英文原版见 translations/en/user-handbook.md为骨架系统讲解 Babel 的安装方式、配置语法、代码生成后的运行时处理、高级配置技巧以及与 ESLint、React、编辑器等周边工具的集成方案。读完本文你将掌握用 Babel CLI 编译项目、用.babelrc精确控制转换行为、用 polyfill 与 runtime 保证生成代码可运行、并能为团队定制专属 preset 的完整能力。引言Babel 是什么Babel 是一个面向 JavaScript 的通用多用途编译器compiler。借助 Babel你既可以使用也可以创造下一代的 JavaScript 语法以及下一代的 JavaScript 工具链。JavaScript 是一门不断演进的语言新规范与提案持续带来新特性。使用 Babel你可以在这些特性尚未在所有环境普及的许多年前就先行使用它们。Babel 的做法是将按照最新标准书写的 JavaScript 代码编译compile down成今天就能在所有环境运行的版本。这一过程被称为源代码到源代码编译source-to-source compiling通常也叫做转译transpiling。例如Babel 可以把 ES2015 的箭头函数语法const square n n * n;转换成const square function square(n) { return n * n; };但 Babel 的能力远不止于此它支持语法扩展例如 React 的 JSX 语法以及用于静态类型检查的 Flow 语法。更进一步Babel 中几乎一切皆插件plugin任何人都可以借助 Babel 的完整能力创建自己的插件再进一步Babel 被拆分为多个核心模块任何人都可以用它们构建下一代 JavaScript 工具。围绕 Babel 已经形成了庞大而多元的生态。本手册将同时覆盖内置 Babel 工具的工作原理以及社区中有用的实践。本仓库即为此目的维护根目录 README.md 列出了该手册的全部翻译版本crowdin.yaml 配置了通过 Crowdin 平台同步各语言翻译的流程CONTRIBUTING.md 则说明了翻译协作的具体方式仓库中还配套了姊妹篇《Babel 插件手册》translations/en/plugin-handbook.md。设置 Babel由于 JavaScript 社区没有单一的构建工具、框架或平台Babel 为所有主流工具提供了官方集成——从 Gulp 到 Browserify从 Ember 到 Meteor无论你的技术栈是什么大概率都有对应的官方集成方式。本手册只覆盖 Babel 内置的设置方式。注意本指南会用到node和npm等命令行工具继续阅读前请确保你对它们足够熟悉。babel-cliBabel 的 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但更好的做法是按项目本地安装理由有二同一台机器上的不同项目可以依赖不同版本的 Babel你可以逐个升级这样你不会对当前工作环境产生隐式依赖项目更便携、更容易搭建。本地安装命令$ 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 } }现在不再直接从命令行运行 Babel而是把命令放进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 的效果相同只是现在使用的是项目本地副本。babel-register第二种常见的运行方式是babel-register只需require文件即可运行 Babel可能更适合你的现有工程结构。注意它不适用于生产环境。部署通过这种方式即时编译的代码被视为不良实践远不如在部署前预先编译但对于构建脚本或其他本地运行的场景它非常适用。先在项目中创建index.jsconsole.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的文件都会先被编译。现在不再运行node index.js而是运行$ node register.js注意你不能在想要编译的同一个文件中注册 Babel因为 Node 执行该文件时Babel 还没来得及编译它require(babel-register); // 不会被编译: console.log(Hello world!);babel-node如果你只是通过nodeCLI 运行一些代码集成 Babel 最简单的途径可能是babel-nodeCLI——它基本可以看作nodeCLI 的即插即用替代品。同样注意它不适用于生产环境更适合本地运行的构建脚本等场景。先确保已安装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-core包。先安装$ npm install babel-corevar babel require(babel-core);如果你有一段 JavaScript 字符串可以用babel.transform直接编译babel.transform(code();, options); // { code, map, ast }如果处理的是文件可以使用异步 APIbabel.transformFile(filename.js, options, function(err, result) { result; // { code, map, ast } });或者同步 APIbabel.transformFileSync(filename.js, options); // { code, map, ast }如果你出于某种原因已经持有 Babel AST也可以直接从 AST 转换babel.transformFromAst(ast, code, options); // { code, map, ast }上述所有方法的options均指 Babel 官方 API 文档中定义的选项集合。可以看到三种 API 的返回值结构统一为{ code, map, ast }——即生成代码、source map 与新的 AST这正是 Babel 以 AST 为核心的架构体现更深层的 parse / transform / generate 三个阶段详见姊妹篇插件手册 translations/en/plugin-handbook.md。配置 Babel你可能已经注意到单独运行 Babel 似乎除了把 JavaScript 文件从一个位置复制到另一个位置什么也没做。这是因为我们还没有告诉 Babel 要做任何事。由于 Babel 是一个被以多种不同方式使用的通用编译器它默认不做任何事。你必须显式地告诉 Babel 该做什么。你可以通过安装**插件plugins或预设presets即插件组**来给 Babel 下达指令。.babelrc在告诉 Babel 做什么之前需要先创建配置文件。只需在项目根目录创建一个.babelrc文件初始内容如下{ presets: [], plugins: [] }这个文件就是你配置 Babel 行为的地方。注意虽然你也可以用其他方式向 Babel 传参但.babelrc文件是约定俗成的最佳方式。babel-preset-es2015首先让 Babel 把 ES2015最新的 JavaScript 标准版本也称 ES6编译为 ES5目前大多数 JavaScript 环境可用的版本。安装 es2015 预设$ npm install --save-dev babel-preset-es2015然后修改.babelrc引入该预设{ presets: [ es2015 ], plugins: [] }babel-preset-react设置 React 同样简单。安装预设$ npm install --save-dev babel-preset-react然后在.babelrc中追加该预设{ presets: [ es2015, react ], plugins: [] }babel-preset-stage-xJavaScript 中还有一些正在通过 TC39负责 ECMAScript 标准的技术委员会流程进入标准的提案。该流程分为 5 个阶段0-4随着提案获得更多支持、更有可能被标准采纳它会依次推进各阶段最终在第 4 阶段被正式纳入标准。Babel 将这些提案打包为 4 个不同的预设babel-preset-stage-0babel-preset-stage-1babel-preset-stage-2babel-preset-stage-3注意没有 stage-4 预设因为第 4 阶段就是上面的es2015预设。每个预设都依赖其后阶段的预设即babel-preset-stage-1依赖babel-preset-stage-2而后者依赖babel-preset-stage-3。安装你感兴趣的阶段$ npm install --save-dev babel-preset-stage-2然后把它加入.babelrc{ presets: [ es2015, react, stage-2 ], plugins: [] }执行 Babel 生成的代码你用 Babel 编译了代码但这并非故事的终点。babel-polyfill几乎所有未来风格的 JavaScript 语法都可以被 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 的代码让你能在这些 API如Array.from正式可用之前就使用它们。Babel 使用优秀的 core-js 作为其 polyfill 实现并结合定制化的 regenerator 运行时让生成器generators和异步函数async functions得以工作。引入 Babel polyfill先用 npm 安装$ npm install --save babel-polyfill然后在任何需要它的文件顶部引入import babel-polyfill;babel-runtime为了实现 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 复制进每一个需要它们的文件中。对比可见语法层面的转换交给插件完成运行时层面的 API 补齐交给 polyfill 与 runtime 分工处理——这是理解 Babel 生成代码能否真正落地的关键心智模型。配置 Babel高级大多数用户仅靠内置预设就能用好 Babel但 Babel 还暴露了远比这更细粒度的能力。手动指定插件Babel 预设本质上只是预配置插件的集合如果你想做点不一样的可以手动指定插件。用法与预设几乎完全相同。先安装一个插件$ npm install --save-dev babel-plugin-transform-es2015-classes然后在.babelrc中添加plugins字段{ plugins: [ transform-es2015-classes ] }这让你对正在执行的转换拥有精确得多的控制粒度。官方插件的完整列表见 Babel 官方插件文档页社区构建的插件也可以在 npm 上搜索babel-plugin关键字。若想学习如何编写自己的插件请阅读本仓库配套的《Babel 插件手册》translations/en/plugin-handbook.md。插件选项许多插件还提供选项来改变其行为。例如很多转换有 “loose宽松” 模式在放弃部分规范行为的同时换取更简单、性能更好的生成代码。为插件添加选项只需做如下修改{ plugins: [ - transform-es2015-classes [transform-es2015-classes, { loose: true }] ] }注意配置语法从字符串变为[插件名, 选项对象]的二元组这是 Babel 支持任意插件自定义选项的统一约定——当你查阅某个插件的 README 时其options字段就对应这里的对象。基于环境自定义 BabelBabel 插件解决的任务五花八门很多是辅助你调试代码或集成工具的开发期工具也有很多是用于在生产环境优化代码的插件。因此按环境区分 Babel 配置是很常见的需求。用.babelrc即可轻松实现{ presets: [es2015], plugins: [], env: { development: { plugins: [...] }, production: { plugins: [...] } } }Babel 会根据当前环境启用env中对应的配置。当前环境取决于process.env.BABEL_ENV当BABEL_ENV不存在时回退到NODE_ENV若也不存在则默认使用development。Unix$ BABEL_ENVproduction [COMMAND] $ NODE_ENVproduction [COMMAND]Windows$ SET BABEL_ENVproduction $ [COMMAND]注意[COMMAND]是你运行 Babel 所用的任何命令如babel、babel-node或使用 register 钩子时的node。提示若希望命令在 Unix 和 Windows 上都能工作可使用cross-env这类跨平台工具。制作自己的预设手动指定插件插件选项基于环境的设置所有这些配置在你的各个项目中反复出现工作量巨大。正因如此Babel 社区被鼓励创建自己的预设——可以是为某个特定 Node 版本定制的预设也可以是为整个公司定制的预设。创建预设很简单。假设你有这样一份.babelrc{ presets: [ es2015, react ], plugins: [ transform-flow-strip-types ] }你只需创建一个遵循babel-preset-*命名约定的新项目请对这个命名空间负责并创建两个文件。首先创建包含必要dependencies的package.json{ name: babel-preset-my-awesome-preset, version: 1.0.0, author: James Kyle methejameskyle.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的内容并把插件/预设字符串替换为require调用module.exports { presets: [ require(babel-preset-es2015), require(babel-preset-react) ], plugins: [ require(babel-plugin-transform-flow-strip-types) ] };然后把它发布到 npm就可以像使用任何预设一样使用它了。其原理清晰可见preset 本质上就是一段返回{ presets, plugins }配置结构的模块Babel 加载它时与读取.babelrc并无二致。Babel 与其他工具Babel 一旦上手就相当直截了当但要弄清它与其他工具如何集成则比较费力。好在 Babel 项目努力与其他项目紧密合作尽可能降低集成难度。静态分析工具新标准为语言带来了大量新语法静态分析工具才刚刚开始利用这些能力。Linting代码检查最流行的 linting 工具之一是 ESLint因此 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这里的关键在于parser字段默认的 ESLint 解析器无法解析 JSX、Flow 等新语法babel-eslint则复用 Babel 的解析能力让 lint 与编译使用同一套语法理解。代码风格Code StyleJSCS 已与 ESLint 合并因此可改用 ESLint 进行代码风格检查。JSCS 曾是把 linting 进一步推进到检查代码风格本身的热门工具。Babel 与 JSCS 两个项目的核心维护者维护着官方集成。更妙的是这个集成如今已内置在 JSCS 中通过--esnext选项即可使用。从 CLI 集成 Babel 只需$ jscs . --esnext或者在.jscsrc文件中添加esnext选项{ preset: airbnb, esnext: true }文档Documentation结合 Babel、ES2015 和 Flow你可以从代码中推断出大量信息。使用 documentation.js 可以非常轻松地生成详细的 API 文档。documentation.js 在后台使用 Babel 来支持所有最新语法包括用于声明代码类型的 Flow 注解。框架Frameworks所有主流 JavaScript 框架都在围绕语言的未来方向对齐其 API也因此投入了大量工作到工具链上。框架不仅有机会使用 Babel还可以以改善用户体验的方式扩展它。ReactReact 大幅调整了其 API 以对齐 ES2015 类。更进一步React 依赖 Babel 来编译其 JSX 语法并弃用了自己的定制工具转而采用 Babel。你可以按照前文“babel-preset-react”一节的说明安装该预设开始使用。React 社区将 Babel 发扬光大如今已有大量由社区构建的转换插件。最值得注意的是babel-plugin-react-transform插件它结合一系列 React 专属转换可以实现**热模块替换hot module reloading**等调试工具。文本编辑器与 IDE用 Babel 引入 ES2015、JSX 和 Flow 语法很有帮助但如果你的文本编辑器不支持它们体验会非常糟糕。因此你需要为文本编辑器或 IDE 配置一个 Babel 插件例如 Sublime Text、Atom、Vim、WebStorm 等主流编辑器均有对应的 Babel 语法支持插件。Babel 支持Babel 拥有庞大且快速增长的用户社区。随着社区成长Babel 希望确保每个人都能获得成功所需的全部资源因此提供了多种获得支持的渠道。请记住所有这些社区都执行行为准则Code of Conduct违反将受到处理请在互动时注意遵守。Babel 也致力于发展一个互助型社区如果你看到有人提出你懂得答案的问题花几分钟帮帮他们并尽量保持友善和理解。主要支持渠道包括论坛Discourse 为 Babel 免费提供了托管版论坛软件可前往 discuss.babeljs.io 参与讨论聊天如需即时支持可加入 slack.babeljs.io 的 Slack 社区问题跟踪Babel 使用 GitHub 的问题跟踪器可查看所有打开与关闭的问题。若要提交新问题先搜索是否已有相同问题再创建新的 bug 报告或功能请求。创建出色的 Babel bug 报告Babel 的问题有时很难远程调试因此需要尽可能多的帮助。多花几分钟打磨一份出色的 bug 报告能显著加快问题解决速度。首先尝试隔离问题——极不可能你的整个工程配置都在导致该问题。如果问题源于某段输入代码试着尽可能多地删除仍然会触发问题的代码缩小到最小复现用例。小结从babel-cli的命令行编译到babel-register/babel-node的运行时集成再到babel-core的编程式 APIBabel 提供了覆盖各种场景的接入方式.babelrc中的presets与plugins则是配置的核心入口配合env字段可实现开发/生产环境差异化配置。编译之外babel-polyfill补齐 API 缺口、babel-runtime抽取公共 helper二者共同保证了生成代码的真实可运行性。若希望进一步深入 Babel 的内部机制并亲手编写插件请继续阅读本仓库的《Babel 插件手册》translations/en/plugin-handbook.md其中详细讲解了 AST、遍历traversal、访问者visitors、路径paths与作用域scopes等核心概念。赞分享文档教程【免费下载链接】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点击查看免费下载相关推荐Babel 用户手册实战指南从安装配置到插件生态的完整工作流Babel 用户手册实战指南从安装配置到插件生态的完整工作流 本篇指南围绕 babel handbook https://link.gitcode.com/i文档教程Babel 用户手册精读从安装配置到插件生态的 Babel 6 实战指南Babel 用户手册精读从安装配置到插件生态的 Babel 6 实战指南 本文以 babel handbook 仓库中的 Babel 用户手册巴西葡萄牙语版文档教程Babel 用户手册实战指南从安装配置到插件生态的完整使用方案Babel 用户手册实战指南从安装配置到插件生态的完整使用方案 Babel 是一个通用的 JavaScript 多用途编译器它通过源码到源码的编译即文档教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考