babel的一些经常使用知识点整理

关于bable的一些知识点整理node

babel-polyfill 的做用 和 runtime react

babel-cli babel-corewebpack

babel-preset-env babel-preset-preset-stage-2es6

babel-loaderweb

babel使用方法:json

  1. 使用单体文件
  2. 使用命令行
  3. 构建工具的插件

运行方式和插件

babel总共分为3个阶段: 解析,转换和生成数组

babel自己不具备任何转换功能, 若是没有plugin,那么通过babel的代码和输入的是相同的。浏览器

babel插件分为两种babel

  1. 语法插件:在解析的过程当中,能使babel可以解析更多的语法
  2. 转译插件: 在转换的过程当中将代码输出。好比将箭头函数转译成正常的函数

用了转译插件后,就不须要用语法插件了,由于同一语法可能同时存在语法插件和转译插件。async

经常使用的一些插件问题

preset

preset是一套规范, 里面包含了几十个转译插件。这是一组插件的集合

preset能够分为下面几种:

  1. 按官方内容: env, react, flow, minify
  2. stage-x, 包含当年最新规范的草案,每一年更新
    每一个stage是不同的,能够分为如下几点

    • Stage 0 - 稻草人: 只是一个想法,通过 TC39 成员提出便可。
    • Stage 1 - 提案: 初步尝试。
    • Stage 2 - 初稿: 完成初步规范。
    • Stage 3 - 候选: 完成规范和浏览器初步实现。
    • Stage 4 - 完成: 将被添加到下一年度发布。
低一级的stage会包含全部高级stage的内容,stage-1包含stage-2,stage-3的全部内容。

stage-4 在下一年更新会直接放到env中,因此没有单独的stage-4可供使用。
    
env是一个每一年更新的preset.

执行顺序

  1. plugin会运行在Preset以前
  2. plugin从前到后顺序执行
  3. preset的顺序是从后向前

插件和 preset 只要列出字符串格式的名字便可。但若是某个 preset 或者插件须要一些配置项(或者说参数),就须要把本身先变成数组。第一个元素依然是字符串,表示本身的名字;第二个元素是一个对象,即配置对象。

"presets": [
    // 带了配置项,本身变成数组
    [
        // 第一个元素依然是名字
        "env",
        // 第二个元素是对象,列出配置项
        {
          "module": false
        }
    ],

    // 不带配置项,直接列出名字
    "stage-2"
]

babel-cli

cli是命令工具,安装了以后,就可以在命令行中使用babel命令来编译文件

因此babel-cli 安装为 devDependencies

### babel-node

babel-node是babel-cli的一部分,不须要独立安装

他使得可以在node环境中,直接运行es2015的代码,不须要额外进行转码。

babel-node = babel-polyfill + babel-register

### babel-register

babel-register 改写require命令, 为它加上一个钩子。每当使用require加载.js、.jsx、.es 和 .es6 后缀名的文件, 就会先用babel进行转码。

使用时,必须先加载require('babel-register')。可是babel-register只会对加载的文件转码,对当前文件是不会骑左右的。

并且他属于实时转码,只适用于开发环境使用

### babel-polyfill

babel只转换js语法,不转换API,如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(好比 Object.assign)都不会转码。

可是能够用babel-polyfill进行转码。

使用时,在全部代码运行以前增长 require('babel-polyfill')。或者更常规的操做是在 webpack.config.js 中将 babel-polyfill 做为第一个 entry。所以必须把 babel-polyfill 做为 dependencies 而不是 devDependencies

可是他的缺点是:

  1. 使用babel-polyfill 会致使打出来的包很是大。babel-polyfill 是一个总体,把全部的方法都加到原型链上。若是咱们只使用了Array.from,可是他会把Object.defineProperty也给加上。
  2. babel-polyfill会污染全局变量,给不少类的原型链上都做了修改。

因此在实际过程当中,一般倾向于用babel-plugin-transform-runtime

可是若是代码中有高版本的js中类型的实例方法([1,2,3].includes(1)),就只能用polyfill了。这个至关因而垫片。

babel-runtime 和 babel-plugin-transform-runtime

bable 会转译js语法,举个async/await例子

// babel 添加一个方法,把 async 转化为 generator
function _asyncToGenerator(fn) { return function () {....}} // 很长很长一段

// 具体使用处
var _ref = _asyncToGenerator(function* (arg1, arg2) {
  yield (0, something)(arg1, arg2);
});

这里_asyncToGenerator在当前文件被定义的,而后被使用了。若是每一个文件都有用async/await方法,那么每一个文件都会有_asyncToGenerator 这段,会致使重复和浪费。

用了babel-plugin-transform-runtime以后,转换的代码就变成

// 从直接定义改成引用,这样就不会重复定义了。
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

// 具体使用处是同样的
var _ref = _asyncToGenerator3(function* (arg1, arg2) {
  yield (0, something)(arg1, arg2);
});

这里就至关于引用了一个模块代码,就不存在重复的问题了。

因此这就是用babel-plugin-transform-runtime的好处,而babel-runtime就是为这些方法提供了集合。因此在使用babel-plugin-transform-runtime的时候,须要babel-runtime作依赖

babel-runtime

babel-runtime 内部集成了

  1. core-js: 转换一些内置类(Promise, Symbol)和静态方法(Array.from等)。绝大部分的引用都是这里作的,自动引入。
  2. regenerator: 是做为core-js的拾遗补漏,主要是generator/yieldasync/await两组作支持。当代码中有generators/async时会自动引入。
  3. helpers

babel-plugin-transform-runtime 不支持 实例方法 (例如 [1,2,3].includes(1))

babel-loader

主要使用在构建工具中。babel-loader和babel-cli同样,会读取.babelrc或者package.json中的babel段做为本身的配置,可是babel-loader必需要和webpack作交互。

名称 做用 备注
babel-cli 容许命令行使用 babel 命令转译文件
babel-node 容许命令行使用 babel-node 直接转译+执行 node 文件 随 babel-cli 一同安装.babel-node = babel-polyfill + babel-register
babel-register 改写 require 命令,为其加载的文件进行转码,不对当前文件转码 只适用于开发环境
babel-polyfill 为全部 API 增长兼容方法 须要在全部代码以前 require,且体积比较大
babel-plugin-transform-runtime & babel-runtime 把帮助类方法从每次使用前定义改成统一 require,精简代码 babel-runtime 须要安装为依赖,而不是开发依赖
babel-loader 使用 webpack 时做为一个 loader 在代码混淆以前进行代码转换

一口(很长的)气了解 babel

相关文章
相关标签/搜索