一文說盡 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客戶端協議 的相關博文,敬請關注!

相關文章
相關標籤/搜索