babel 插件開發案例

寫在前面

本文將以把es6的語法let改成var爲例,講述如何編寫一個babel插件。其中涉及到一些babel的基本知識,babel的工做流程,語法抽象樹等。前端

babel簡介

關於babel 官網作了以下解釋:node

Babel 是一個工具鏈,主要用於在舊的瀏覽器或環境中將 ECMAScript 2015+ 代碼轉換爲向後兼容版本的 JavaScript 代碼react

相信你們在開發中或多或少的都使用過bable對代碼進行編譯。在babel配置文件.babelrc中最主要就是對presetsPlugins的配置。其中presets通俗來講就是某一類的插件轉譯集合,好比說babel官方封裝好的@babel/preset-react中就包括如下插件@babel/plugin-syntax-jsx@babel/plugin-transform-react-jsx@babel/plugin-transform-react-display-name。而Plugins相對來講功能比較單一,好比transform-es2015-arrow-functions,這個插件只負責轉譯es2015新增的箭頭函數。es6

因此在咱們的平常開發中也能夠根據本身的需求開發bebal插件,從而提升開發效率。編程

babel的編譯過程

Babel轉碼的過程分三個階段:解析(parse)、轉換(transform)、生成(generate)。下面這張圖能夠很好的說明babel的工做過程瀏覽器

image

  • 解析,解析步驟接收代碼並輸出 AST。
  • 轉換,轉換步驟接收AST並對其進行遍歷,在此過程當中對節點進行添加、更新及移除等操做
  • 生成,代碼生成步驟把最終(通過一系列轉換以後)的 AST 轉換成字符串形式的代碼,同時還會建立源碼映射(source maps)。

其中,解析、生成階段由Babel核心完成,而轉換階段,則由Babel插件完成,這也是本文的重點。bash

抽象語法樹(AST)

在計算機科學中,抽象語法樹(Abstract Syntax Tree,AST),或簡稱語法樹(Syntax tree),是源代碼語法結構的一種抽象表示。它以樹狀的形式表現編程語言的語法結構,樹上的每一個節點都表示源代碼中的一種結構。之因此說語法是「抽象」的,是由於這裏的語法並不會表示出真實語法中出現的每一個細節。微信

開發一個babel插件必定要對AST有所瞭解,上面是維基百科對抽象語法樹的解釋babel

舉個例子:編程語言

var a = 1;
複製代碼

轉換成的AST結構爲:

這裏是能夠實時查看代碼ast結構的網站astexplorer.net/,有助於更好的瞭解ast以及編寫babel插件


開發babel插件

安裝@babel/cli,@babel/core

可用於從命令行編譯文件

"@babel/cli": "^7.1.5",
 "@babel/core": "^7.1.6",
複製代碼

新建js文件

新建一個babel-letToVar.js文件,代碼以下

function letToVar(babel) {

  const { types: t, template } = babel;
  return visitor = { };
}

module.exports = letToVar;
複製代碼

咱們能夠在letToVar這個方法中接收babel對象。

visitor 屬性是這個插件的主要訪問者,且其中的每一個函數接收2個參數:path 和 stat。訪問者是一個用於 AST 遍歷的跨語言的模式。簡單的說它們就是一個對象,定義了用於在一個樹狀結構中獲取具體節點的方法。

咱們的需求是將let轉換成var,那麼咱們須要添加一個VariableDeclaration訪問者方法

function letToVar(babel) {
  const { types: t, template } = babel;
  const visitor = {
    VariableDeclaration(path) {
      if(path.get('kind').node!='let')return;
        path.node.kind='var';
      }
  };
  return {visitor};
}

module.exports = letToVar;
複製代碼

咱們能夠經過path.get()方法獲取到kind,並判斷他是否是爲let,若是是就將其改成var,以實現咱們的需求。

下面咱們能夠運行看一下效果是否符合咱們的預期。

新建.eslintrc文件

咱們能夠直接在此文件中引入咱們的babel-letToVar.js文件

{
  "plugins": [ "./babel-letToVar.js"]
}
複製代碼

運行並查看效果

咱們能夠在終端運行下面命令,將inedx.js文件編譯後輸出到dest.js文件中。

$ babel index.js --out-file dest.js
複製代碼

下圖是運行效果,能夠看到已經實現了咱們的需求。

總結

本文演示的只是一個簡單的babel插件的開發,咱們在轉換的過程當中拿到代碼的AST結構後,就能夠爲所欲爲的對代碼進行增長、刪除、修改。咱們還能夠經過編寫babel插件實現更多的功能,好比刪除代碼中全部console.log等。

做者簡介

卓月,銅板街前端開發工程師,2018年3月加入團隊,目前主要負責自營端 H5 項目開發。

更多精彩內容,請掃碼關注 「銅板街科技」 微信公衆號。
相關文章
相關標籤/搜索