<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Babel 插件

          共 4951字,需瀏覽 10分鐘

           ·

          2021-08-06 10:20

          作者:知否

          來源:SegmentFault 思否社區(qū)


          Babel 是一個編譯器,和其他編譯器一樣,編譯過程分為三個階段,分別是解析(parsing)、轉(zhuǎn)換(transforming)和生成(generate)。其中分析和生成階段由 Babel 核心完成,而轉(zhuǎn)換階段,則由Babel插件完成。所以如果我們要實現(xiàn)代碼的轉(zhuǎn)換,需要為 Babel 添加插件。Babel 也提供了很多的接口來供我們編寫自身的插件來轉(zhuǎn)換我們的實際代碼。

          插件的介紹

          下面是一個典型的 Babel 插件結(jié)構(gòu):

          export default function({ types: babelTypes }) {
            return {
              visitor: {
                Identifier(path, state) {},
                ASTNodeTypeHere(path, state) {}
              }
            };
          };

          其中我們需要關注的內(nèi)容如下:

          • babelType:類似 lodash 那樣的工具集,主要用來操作 AST 節(jié)點,比如創(chuàng)建、校驗、轉(zhuǎn)變等。例如判斷某個節(jié)點是不是標識符。

          • path:AST 中有很多節(jié)點,每個節(jié)點可能有不同的屬性,并且節(jié)點之間可能存在關聯(lián)。path 是個對象,它代表了兩個節(jié)點之間的關聯(lián)。我們可以在 path 上訪問到節(jié)點的屬性,也可以通過 path 來訪問到關聯(lián)的節(jié)點。

          • state:代表了插件的狀態(tài),我們可以通過 state 來訪問插件的配置項。

          • visitor:Babel 采取遞歸的方式訪問 AST 的每個節(jié)點,之所以叫做 visitor,只是因為有個類似的設計模式叫做訪問者模式,不用在意背后的細節(jié)。

          • Identifier、ASTNodeTypeHere:AST 的每個節(jié)點,都有對應的節(jié)點類型,比如標識符、函數(shù)聲明等,可以在 visitor 上聲明同名的屬性,當 Babel 遍歷到相應類型的節(jié)點,屬性對應的方法就會被調(diào)用,傳入的參數(shù)就是 path、state。

          插件的使用

          例如我們來實現(xiàn)一個簡單的插件,將所有名稱為 hello 的標識符,轉(zhuǎn)成 xkd。
          首先要確保已經(jīng)安裝了 @babel/cli 依賴,如果沒有可以執(zhí)行下述命令:
          npm install --save-dev @babel/cli
          然后可以開始創(chuàng)建插件,判斷標識符的名稱是否是 a,如果是則替換成 xkd,plugin.js 文件內(nèi)容如下所示:
          module.exports = function({ types: babelTypes }) {
              return {
                name: "simple-plugin-replace",
                visitor: {
                  Identifier(path, state) {
                    if (path.node.name === 'a') {
                      path.node.name = 'xkd';
                    }
                  }
                }
              };
          };
          然后在 index.js 文件中編寫源代碼,例如:
          var a = 10;
          function func(){
              var a = 20;
              console.log(a);
          }
          執(zhí)行如下命令:
          npx babel --plugins ./plugin.js index.js
          輸出的轉(zhuǎn)碼結(jié)果為:
          "use strict";

          var xkd = 10;
          function func() {
              var xkd = 20;
              console.log(xkd);
          }
          可以看到,代碼中的所有標識符 a 都被替換成了 xkd。

          插件配置

          插件可以有自己的配置項。我們可以修改前面的例子,看下在 Babel 插件中如何獲取配置項。
          示例:
          例如我們修改 .babelrc 文件中的配置項:
          {
              "plugins": [ ["./plugin", {
                "a""one",
                "b""two"
              }] ]
          }
          然后修改插件代碼,從 state.opts 中獲取到配置參數(shù)。
          module.exports = function({ types: babelTypes }) {
            return {
              name: "simple-plugin-replace",
              visitor: {
                Identifier(path, state) {
                  let name = path.node.name;
                  if (state.opts[name]) {
                    path.node.name = state.opts[name];
                  }
                }
              }
            };
          };
          在 index.js 文件中寫入需要用到的測試代碼:
          let a = 10;
          let b = 20;
          運行轉(zhuǎn)碼命令 npx babel index.js,輸出轉(zhuǎn)碼后的結(jié)果如下:
          let one = 10;
          let two = 20;

          轉(zhuǎn)譯插件

          插件可以分為兩種,分是轉(zhuǎn)譯插件和語法插件,轉(zhuǎn)譯插件可以用于轉(zhuǎn)譯代碼。同一類語法可能同時存在語法插件版本和轉(zhuǎn)譯插件版本,如果我們使用了轉(zhuǎn)譯插件,就不用再使用語法插件了,因為轉(zhuǎn)換插件將啟用相應的語法插件。

          ES3

          • member-expression-literals

          • property-literals

          • reserved-words

          ES5

          • property-mutators

          ES2015

          • arrow-functions

          • block-scoped-functions

          • block-scoping

          • classes

          • computed-properties

          • destructuring

          • duplicate-keys

          • for-of

          • function-name

          • instanceof

          • literals

          • new-target

          • object-super`

          • parameters

          • shorthand-properties

          • spread

          • sticky-regex

          • template-literals

          • typeof-symbol

          • unicode-escapes

          • unicode-regex

          ES2016

          • exponentiation-operator

          ES2017

          • async-to-generator

          ES2018

          • async-generator-functions

          • dotall-regex

          • named-capturing-groups-regex

          • object-rest-spread

          • optional-catch-binding

          • unicode-property-regex

          Modules

          • modules-amd

          • modules-commonjs

          • modules-systemjs

          • modules-umd

          Experimental

          • class-properties

          • decorators

          • do-expressions

          • export-default-from

          • export-namespace-from

          • function-bind

          • function-sent

          • logical-assignment-operators

          • nullish-coalescing-operator

          • numeric-separator

          • optional-chaining

          • partial-application

          • pipeline-operator

          • private-methods

          • throw-expressions

          • private-property-in-object

          語法插件

          當我們添加語法插件之后,在解析這一步就使得 Babel 能夠解析特定類型的語法。
          或者也可以從 Babel 解析器提供任何插件選項,例如 .babelrc 文件中可以像下面這樣配置:
          {
            "parserOpts": {
              "plugins": ["jsx""flow"]
            }
          }


          點擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,掃描下方”二維碼“或在“公眾號后臺回復“ 入群 ”即可加入我們的技術交流群,收獲更多的技術文章~

          - END -


          瀏覽 27
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲一级a免费在线观看 | 五月天伊人五一狼人插 | 禁18网站 | 操逼性交毛片 | 三级操逼|