Skip to main content

Babel 手册

Babel 是什么?

Babel 是一个通用的多用途 JavaScript 编译器。它主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。

babel 总共分为三个阶段:解析,转换,生成。

babel 本身不具有任何转化功能,它把转化的功能都分解到一个个 plugin 里面。因此当我们不配置任何插件时,经过 babel 的代码和输入是相同的。

作用

  • 语法转换
  • 源码转换
  • 通过 Polyfill 方式在目标环境中添加缺失的特性
  • 等等...

安装使用

  1. 安装所需的包

    npm install --save-dev @babel/core @babel/cli @babel/preset-env
  2. 在你的项目中创建新文件

    1. 你是否希望编译 node_modules 目录下的模块?

      babel.config.js 文件可以满足你的的需求!

      module.exports = function (api) {
      api.cache(true);

      const presets = [ ... ];
      const plugins = [ ... ];

      return {
      presets,
      plugins
      };
      }
  1. 你是否只是需要一个简单的并且只用于单个软件包的配置?

    .babelrc 文件适合你!

    "babel": {
    "presets": [ ... ],
    "plugins": [ ... ],
    }
  1. package.json

    配置一个属性值babel

    {
    "name": "my-package",
    "version": "1.0.0",
    "babel": {
    "presets": [ ... ],
    "plugins": [ ... ],
    }
    }

配置 Babel

你可以通过安装 插件(plugins)预设(presets)来指示 Babel 去做什么事情。 preset 作为 Babel plugins的组合转换你的代码。

Plugins

参数

参数由插件名和参数对象组成一个数组,可以在配置文件中设置。

{
"plugins": [
[
"transform-async-to-module-method",
{
"module": "bluebird",
"method": "coroutine"
}
]
]
}

执行顺序

  • 插件在 Presets 前运行
  • 插件顺序从前往后排列

Presets

参数

参数由插件名和参数对象组成一个数组,可以在配置文件中设置。

格式

  • 不带配置项,直接列出名字
  • 带了配置项,自己变成数组,[名字, 配置项对象]
{
"presets": [
["@babel/preset-env", {
"loose": true,
"modules": false
}]
]
}

执行顺序

逆序排列的(从后往前),主要是为了保证向后兼容,我们在编排 preset 的时候,也要注意顺序,其实只要按照规范的时间顺序列出即可。

babel-preset-stage-x

stage-x preset 中的语法转换会随着被批准为 JavaScript 新版本的组成部分而进行相应的改变(例如 ES6/ES2015)。

TC39 将提案分为以下几个阶段:

  • Stage 0 - 设想(Strawman):只是一个想法,可能有 Babel 插件。
  • Stage 1 - 建议(Proposal):这是值得跟进的。
  • Stage 2 - 草案(Draft):初始规范。
  • Stage 3 - 候选(Candidate):完成规范并在浏览器上初步实现。
  • Stage 4 - 完成(Finished):将添加到下一个年度版本发布中。

env

env 的核心目的是通过配置得知目标环境的特点,然后只做必要的转换,而无需对目标环境所需的语法转换(以及可选的浏览器polyfill)进行管理,这样可以使包更小。

npm install --save-dev @babel/preset-env

@babel/preset-env 接受您指定的任何目标环境,并根据其映射检查它们,以编译插件列表,并将其传递给Babel。常见用法如下

{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
}
}]
]
}

或者可以配置 .browserslistrc

last 2 versions
safari >= 7

或者 package.json

{
"browserslist": "last 2 versions, safari >= 7"
}

babel-preset-env

常用包解释

babel-core

版本

babel-core

@babel/core

作用

  • 加载和处理配置
  • 加载插件
  • 调用 Parser 进行语法解析,生成 AST
  • 调用 Traverser 遍历AST,并使用访问者模式应用'插件'对 AST 进行转换
  • 生成代码,包括SourceMap转换和源代码生成

使用

Using npm

npm install --save-dev @babel/core

or using yarn

yarn add @babel/core --dev

package.json

{
devDependencies: {
'@babel/core': '^x.x.x',
}
}

babel-polyfill

版本

babel-polyfill

@babel/polyfill

作用

Babel默认只转换新的JavaScript句法(syntax),而不转换新的API, 以及一些定义在全局对象上的方法都不会转码。babel-polyfill用于对已经存在的语法和api实现一些浏览器还没有实现的api,对浏览器的一些缺陷做一些修补。

使用

Using npm

npm install --save-dev @babel/polyfill

or using yarn

yarn add @babel/polyfill --dev

package.json

{
devDependencies: {
'@babel/polyfill': '^x.x.x',
}
}

Note

polyfill的包有点大,在生产环境下并不需要全量引入,我们可以使用引入babel-plugin-transform-runtime这个包。因为Babel使用很小的帮助器来完成诸如的功能_extend。默认情况下,它将被添加到需要它的每个文件中。有时不需要重复,特别是当您的应用程序分布在多个文件中时。

这是@babel/plugin-transform-runtime插件的来源:所有帮助程序都将引用该模块,@babel/runtime以避免在编译后的输出中出现重复。运行时将被编译到您的构建中。

该转换器的另一个目的是为您的代码创建一个沙盒环境。如果你直接导入core-js@babel/polyfill,它提供了诸如内置插件PromiseSetMap那些会污染全局范围。尽管这对于应用程序或命令行工具可能是可以的,但是如果您的代码是要发布供他人使用的库,或者您无法完全控制代码运行的环境,则将成为一个问题。

转换器会将这些内置别名作为别名,core-js因此您可以无缝使用它们,而无需使用polyfill

使用

生产环境

npm install --save-dev @babel/plugin-transform-runtime

@babel/runtime作为生产依赖性(因为它是针对“运行时(runtime)”的)

npm install --save @babel/runtime

转换插件通常仅在开发中使用,但是运行时本身将取决于部署的代码。

.babelrc

{
"plugins": ["@babel/plugin-transform-runtime"]
}

带配置项

{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}

参考资料

Babel官网

babel-handbook 中文文档

深入浅出 Babel 上篇:架构和原理 + 实战

一口(很长的)气了解 babel