一文说尽 Babel 的前世此生

做者: 多巴胺

1、Babel 是什么

Babel 是一个能够将 使用ES2015+语法的代码 编译成 向后兼容 的代码的工具。当咱们使用 EcmaScript 较高版本的 Javascript 语法特性的时候,将所写代码转换成兼容 ES5 的代码,目的支持尽量多的平台。对于转换的规则,主要有分为如下两类:javascript

  • Sytanx类型。例如箭头函数、const/let 等语法特性,babel 能够经过各类插件实现兼容。
  • 运行时api。例如数组的静态方法Array.from()、实例方法 arr.includes() 等,须要引入 corejs 做为 polyfill(垫片),从而可以在运行时提供支持。

2、功能模块构成

  • 核心库——@babel/core

@babel/core 模块是一个能够完成代码字符串转换的库,babel全部的插件都是经过核心库来进行开发和加载的,以下是官方给的使用示例:前端

const babel = require("@babel/core");

babel.transform("code", optionsObject);
  • 命令行工具——@babel/cli

当咱们使用核心库的时候,通常不直接再代码中调用@babel/core提供的api,而是使用bable提供的命令行工具来进行源代码的转换。通常咱们在使用的时候,将其做为 package.json 文件的一个 scripts 脚本进行配置,用于对指定文件夹的 js 语言作转换。例如如下示例,当咱们运行 npm run babel,便可将根目录的 src 目录下全部的 js 文件进行转换,完成后放置于根目录 dist 下。java

"scripts": {
    "babel": "babel src --out-dir dist"
  },

babel 的语法转换功能依赖于各类插件。好比当咱们使用箭头函数转换的插件  @babel/plugin-transform-arrow-functions ,当咱们配置此插件后,源代码中的箭头函数将会被转换成普通的 Javascript 函数。node

// 源代码
const print = (a) => console.log(a)

// 目标代码
var print = function print(a) {
  return console.log(a);
};
  • 插件集合——Presets

顾名思义,preset(预装置)就是多个插件的集合。例如,当咱们的开发场景中须要使用箭头函数和可选操做符,那么咱们能够将 @babel/plugin-transform-arrow-functions 和 @babel/plugin-proposal-optional-chaining 进行组合造成一个preset,当咱们再次遇到须要使用箭头函数和可选操做符的转换场景的时候,直接使用此 preset,没必要要在单个配置 Plugin。
官方提供了四个Presets,其中 @babel/preset-env 是咱们经常使用的 preset,它提供了最新的 Javascript 语法转换,使用它,能够作到 Makes your life easier!sql

  • 配置文件——推荐以 js 的形式

上文的介绍中,有不少的具体配置,那咱们在什么地方进行 Plugin/Presets 的配置呢?官方给了多个文件类型和多个不一样的文件,此处推荐使用 babel.config.js——即在根目录下建立 babel.config.js 并在其中导出 presets 和 plugins 对象。
当咱们使用 Javascript 进行配置的时候,拥有更多的控制能力。能够以代码的方式控制在不一样目标环境下应用不一样的语法转换规则。npm

// 根目录下的 babel.config.js 文件中的内容

const plugins = [
    '@babel/plugin-transform-arrow-functions',
    '@babel/plugin-proposal-optional-chaining'
]

const presets = [
    ['@babel/env', {
        useBuiltIns: 'usage',
        corejs: 3
    }]
]

module.exports = { plugins, presets }

3、Babel 的具体配置规则

在使用 babel 以前,咱们首先安装 @babel/core, @babel/cli,命令以下:json

npm install --save-dev @babel/cli @babel/core

在你项目的编译脚本中,添加以下脚本配置:api

"scripts": {
    "babel": "babel src --out-dir dist"
  },

1. 仅作 Syntax 转换

当咱们仅仅只想尝试某一个新的 Javascript 语法特性的时候,能够直接安装对应语法特性的 Plugin,例如当咱们使用可选操做符 ( ?. ) 的时候,咱们就能够安装 @babel/plugin-proposal-optional-chaining。数组

npm install --save-dev @babel/plugin-proposal-optional-chaining

以后,再更目录下建立 .babel.js 文件,写入此 Plugin 的配置并导出。babel

const plugins = [
    '@babel/plugin-transform-arrow-functions',
]

module.exports = { plugins }

那么,咱们尝试使用会发现,转换成功了。

// 源代码
const baz = obj?.foo?.bar?.baz;

// 转换后
var baz = obj === null || obj === void 0 ? void 0 : (_obj$foo = obj.foo) === null || _obj$foo === void 0 ? void 0 : (_obj$foo$bar = _obj$foo.bar) === null || _obj$foo$bar === void 0 ? void 0 : _obj$foo$bar.baz;

2. 推荐用法

为了尽可能少的关心插件,咱们可使用官方提供的 @babel/preset-env。当咱们配置此 Preset 时,让 babel 同时支持 Syntax 层面和 built-ins 层面的转化。为了支持 built-ins 转换,咱们须要添加 useBuiltIns 的配置,具体步骤以下:

// 安装 @babel/preset-env
npm install --save-dev @babel/preset-env
// 安装 @core-js@3
// 因为 built-in 是运行时环境的依赖,因此要使用 --save
npm install --save core-js@3

// .babel.js 配置
const presets = [
    ['@babel/env', {
        // 此配置项的值能够配置为 entry/usage
        // entry: 注入目标环境不支持的全部 built-in 类型语法
        // usage: 注入目标环境不支持的全部被用到的 built-in 类型语法
        useBuiltIns: 'usage',
              // built-in 须要 corejs 的支持。corejs3 支持对象的实例方法
        corejs: 3
    }]
]

module.exports = { presets }

3. @babel/plugin-transform-runtime

使用此插件的缘由主要有两个:

  • 默认状况下,babel 再作 built-in 类型的转换时,会在源代码每一个文件里面引入 core-js 的 helper 函数,有时这是没有必要的。当使用 @babel/plugin-transform-runtime 时,全部的 helpers 都只会引 @babel/runtime。
  • 此插件能够提供一个运行的沙箱环境。若是直接使用 core-js,那对于 Promise、Set 等对象,都会污染全局做用域。若是你如今开发的是一个工具包,你使用了 core-js 提供了 Promise、Set 的语法转换。当别人在他的项目里引入了你的工具包,偏偏他的项目中已经实现了 Promise、Set 等函数,这就会致使复杂的冲突问题。

配置以下所示:

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

// 安装生产环境依赖
// 此处和是否使用 core-js 及 core-js 版本有关
// corejs: false
npm install --save @babel/runtime
// corejs: 3 如下配置示例中的 corejs 版本
npm install --save @babel/runtime-corejs3
// corejs: 2
npm install --save @babel/runtime-corejs2

// .babel.js 配置详情
// 这是在 nodejs 配置中推荐的使用方式
const plugins = [
    ['@babel/plugin-transform-runtime', {
        corejs: 3
    }]
]

// 此处须要注意,当咱们使用了 @babel/runtime-corejs2,原先的 corejs@3 便不须要使用了
const presets = [
    ['@babel/env']
]

module.exports = { plugins, presets }

📕领取福利

动动小手,关注做者公众号吧!更多精彩内容等着你哦~

  • 回复 Node.js教程 领取入门课程
  • 回复 前端书单 领取前端技术系列书籍

后续将在公众号持续更新 Node.js实现Mysql客户端协议 的相关博文,敬请关注!

相关文章
相关标签/搜索