1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Babel 插件

        共 4951字,需瀏覽 10分鐘

         ·

        2021-08-06 10:20

        作者:知否

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


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

        插件的介紹

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

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

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

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

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

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

        • visitor:Babel 采取遞歸的方式訪問 AST 的每個(gè)節(jié)點(diǎn),之所以叫做 visitor,只是因?yàn)橛袀€(gè)類似的設(shè)計(jì)模式叫做訪問者模式,不用在意背后的細(xì)節(jié)。

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

        插件的使用

        例如我們來實(shí)現(xiàn)一個(gè)簡單的插件,將所有名稱為 hello 的標(biāo)識符,轉(zhuǎn)成 xkd。
        首先要確保已經(jīng)安裝了 @babel/cli 依賴,如果沒有可以執(zhí)行下述命令:
        npm install --save-dev @babel/cli
        然后可以開始創(chuàng)建插件,判斷標(biāo)識符的名稱是否是 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);
        }
        可以看到,代碼中的所有標(biāo)識符 a 都被替換成了 xkd。

        插件配置

        插件可以有自己的配置項(xiàng)。我們可以修改前面的例子,看下在 Babel 插件中如何獲取配置項(xiàng)。
        示例:
        例如我們修改 .babelrc 文件中的配置項(xiàng):
        {
            "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;
        運(yùn)行轉(zhuǎn)碼命令 npx babel index.js,輸出轉(zhuǎn)碼后的結(jié)果如下:
        let one = 10;
        let two = 20;

        轉(zhuǎn)譯插件

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

        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

        語法插件

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


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

        - END -


        瀏覽 27
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            女生抠逼视频 | 午夜精品一区二区三区AA毛片 | 久久偷拍人| 免费成人视频播放 | 靠逼在线 | 日韩欧美精品在线观看 | 美女肏逼网站影院 | 操逼黄色视频网站 | 精品无码在线观看 | 日韩无码成人 |