babel使用
介绍
Babel 是一个通用的多用途 JavaScript 编译器。通过 Babel 你可以使用(并创建)下一代的 JavaScript,以及下一代的 JavaScript 工具。 作为一种语言,JavaScript 在不断发展,新的标准/提案和新的特性层出不穷。 在得到广泛普及之前,Babel 能够让你提前(甚至数年)使用它们。
Babel 把用最新标准编写的 JavaScript 代码向下编译成可以在今天随处可用的版本。 这一过程叫做“源码到源码”编译, 也被称为转换编译(transpiling,是一个自造合成词,即转换+编译。以下也简称为转译)。
安装 Babel
由于 JavaScript 社区没有统一的构建工具、框架、平台等等,因此 Babel 正式集成了对所有主流工具的支持。 从 Gulp 到 Browserify,从 Ember 到 Meteor,不管你的环境设置如何,Babel 都有正式的集成支持。
本手册的目的主要是介绍 Babel 内建方式的安装,不过你可以访问交互式的安装页面来查看其它的整合方式。
babel-cli
Babel 的 CLI 是一种在命令行下使用 Babel 编译文件的简单方法。
让我们先全局安装它来学习基础知识。
1 | $ npm install --global babel-cli |
我们可以这样编译我们的第一个文件
1 | $ babel my-file.js |
这将把编译后的结果直接输出至终端。使用 --out-file
或着 -o
可以将结果写入到指定的文件。
1 | $ babel example.js --out-file compiled.js |
如果我们想要把一个目录整个编译成一个新的目录,可以使用 --out-dir
或者 -d
。
1 | $ babel src --out-dir lib |
在项目内运行 Babel CLI
尽管你可以把 Babel CLI 全局安装在你的机器上,但是按项目逐个安装在本地会更好。
有两个主要的原因。
- 在同一台机器上的不同项目或许会依赖不同版本的 Babel 并允许你有选择的更新。
- 这意味着你对工作环境没有隐式依赖,这让你的项目有很好的可移植性并且易于安装。
要在(项目)本地安装 Babel CLI 可以运行:
1 | $ npm install --save-dev babel-cli |
注意: 因为全局运行 Babel 通常不是什么好习惯所以如果你想要卸载全局安装的 Babel 的话,可以运行:
1 | $ npm uninstall --global babel-cli |
安装完成后,你的 package.json
应该如下所示:
1 | { |
现在,我们不直接从命令行运行 Babel 了,取而代之我们将把运行命令写在 npm scripts 里,这样可以使用 Babel 的本地版本。
只需将 "scripts"
字段添加到你的 package.json
文件内并且把 babel 命令写成 build
字段。.
1 | { |
现在可以在终端里运行:
1 | npm run build |
这将以与之前同样的方式运行 Babel,但这一次我们使用的是本地副本。
babel-register
下一个常用的运行 Babel 的方法是通过 babel-register
。这种方法只需要引入文件就可以运行 Babel,或许能更好地融入你的项目设置。
但请注意这种方法并不适合正式产品环境使用。 直接部署用此方式编译的代码不是好的做法。 在部署之前预先编译会更好。 不过用在构建脚本或是其他本地运行的脚本中是非常合适的。
让我们先在项目中创建 index.js
文件。
1 | console.log("Hello world") |
如果我们用 node index.js
来运行它是不会使用 Babel 来编译的。所以我们需要设置 babel-register
。.
首先安装 babel-register
。
1 | $ npm install --save-dev babel-register |
接着,在项目中创建 register.js
文件并添加如下代码:
1 | require("babel-register"); |
这样做可以把 Babel 注册到 Node 的模块系统中并开始编译其中 require
的所有文件。
现在我们可以使用 register.js
来代替 node index.js
来运行了。
1 | $ node register.js |
注意:你不能在你要编译的文件内同时注册 Babel,因为 node 会在 Babel 编译它之前就将它执行了。
1 | require("babel-register"); |
babel-node
如果你要用 node
CLI 来运行代码,那么整合 Babel 最简单的方式就是使用 babel-node
CLI,它是 node
CLI 的替代品。
但请注意这种方法并不适合正式产品环境使用。 直接部署用此方式编译的代码不是好的做法。 在部署之前预先编译会更好。 不过用在构建脚本或是其他本地运行的脚本中是非常合适的。
首先确保 babel-cli
已经安装了。
1 | $ npm install --save-dev babel-cli |
然后用babel-node
来替代node
运行所有的代码。
如果用 npm script
的话只需要这样做:
1 | { |
要不然的话你需要写全 babel-node
的路径。
1 | - node script.js |
提示:你可以使用
npm-run
babel-core
如果你需要以编程的方式来使用 Babel,可以使用 babel-core
这个包。
首先安装 babel-core
。
1 | $ npm install babel-core |
1 | var babel = require("babel-core"); |
字符串形式的 JavaScript 代码可以直接使用 babel.transform
来编译。
1 | babel.transform("code();", options); |
如果是文件的话,可以使用异步 api:
1 | babel.transformFile("filename.js", options, function(err, result) { |
或者是同步 api:
1 | babel.transformFileSync("filename.js", options); |
要是已经有一个 Babel AST(抽象语法树)了就可以直接从 AST 进行转换。
1 | babel.transformFromAst(ast, code, options); |
对于上述所有方法,options
指的都是 http://babeljs.io/docs/usage/options/
配置 Babel
你或许已经注意到了,目前为止通过运行 Babel 自己我们并没能“翻译”代码,而仅仅是把代码从一处拷贝到了另一处。
这是因为我们还没告诉 Babel 要做什么。
由于 Babel 是一个可以用各种花样去使用的通用编译器,因此默认情况下它反而什么都不做。你必须明确地告诉 Babel 应该要做什么。
你可以通过安装插件(plugins)或预设(presets,也就是一组插件)来指示 Babel 去做什么事情。
.babelrc
在我们告诉 Babel 该做什么之前,我们需要创建一个配置文件。你需要做的就是在项目的根路径下创建 .babelrc
文件。然后输入以下内容作为开始:
1 | { |
这个文件就是用来告诉Babel做你要他做的事情的配置文件。
注意:尽管你也可以用其他方式给 Babel 传递选项,但
.babelrc
文件是约定也是最好的方式。
babel-preset-es2015
我们先从让 Babel 把 ES2015(最新版本的 JavaScript 标准,也叫做 ES6)编译成 ES5(现今在大多数 JavaScript 环境下可用的版本)开始吧。
我们需要安装 "es2015" Babel 预设:
1 | $ npm install --save-dev babel-preset-es2015 |
我们修改 .babelrc
来包含这个预设。
1 | { |
babel-preset-stage-x
JavaScript 还有一些提案,正在积极通过 TC39(ECMAScript 标准背后的技术委员会)的流程成为标准的一部分。
这个流程分为 5(0-4)个阶段。 随着提案得到越多的关注就越有可能被标准采纳,于是他们就继续通过各个阶段,最终在阶段 4 被标准正式采纳。
以下是4 个不同阶段的(打包的)预设:
babel-preset-stage-0
babel-preset-stage-1
babel-preset-stage-2
babel-preset-stage-3
注意 stage-4 预设是不存在的因为它就是上面的
es2015
预设。
以上每种预设都依赖于紧随的后期阶段预设。例如,babel-preset-stage-1
依赖 babel-preset-stage-2
,后者又依赖 babel-preset-stage-3
。.
使用的时候只需要安装你想要的阶段就可以了:
1 | $ npm install --save-dev babel-preset-stage-2 |
然后添加进你的 .babelrc
配置文件。
1 | { |
执行 Babel 生成的代码
即便你已经用 Babel 编译了你的代码,但这还不算完。
babel-polyfill
Babel 几乎可以编译所有时新的 JavaScript 语法,但对于 APIs 来说却并非如此。
比方说,下列含有箭头函数的需要编译的代码:
1 | function addAll() { |
最终会变成这样:
1 | function addAll() { |
然而,它依然无法随处可用因为不是所有的 JavaScript 环境都支持 Array.from
。
Uncaught TypeError: Array.from is not a function
为了解决这个问题,我们使用一种叫做 Polyfill(代码填充,也可译作兼容性补丁) 的技术。 简单地说,polyfill 即是在当前运行环境中用来复制(意指模拟性的复制,而不是拷贝)尚不存在的原生 api 的代码。 能让你提前使用还不可用的 APIs,Array.from
就是一个例子。
Babel 用了优秀的 core-js 用作 polyfill,并且还有定制化的 regenerator 来让 generators(生成器)和 async functions(异步函数)正常工作。
要使用 Babel polyfill,首先用 npm 安装它:
1 | $ npm install --save babel-polyfill |
然后只需要在文件顶部导入 polyfill 就可以了:
1 | import "babel-polyfill"; |
babel-runtime
为了实现 ECMAScript 规范的细节,Babel 会使用“助手”方法来保持生成代码的整洁。
由于这些助手方法可能会特别长并且会被添加到每一个文件的顶部,因此你可以把它们统一移动到一个单一的“运行时(runtime)”中去。
通过安装 babel-plugin-transform-runtime
和 babel-runtime
来开始。
1 | $ npm install --save-dev babel-plugin-transform-runtime |
然后更新 .babelrc
:
1 | { |
现在,Babel 会把这样的代码:
1 | class Foo { |
编译成:
1 | import _classCallCheck from "babel-runtime/helpers/classCallCheck"; |
这样就不需要把 _classCallCheck
和 _createClass
这两个助手方法放进每一个需要的文件里去了。
配置 Babel(进阶)
大多数人使用 Babel 的内建预设就足够了,不过 Babel 提供了更多更细粒度的能力。
- 本文标题:babel使用
- 本文作者:hddhyq
- 本文链接:https://hddhyq.github.io/2017/10/22/babel使用/
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!