【W(wǎng)ebpack】AST、babel、依賴

babel

babel的原理

1、parse:把代碼變成AST
2、traverse:遍歷AST進(jìn)行修改;
3、generate:把AST變成代碼2

看下AST到底是什么東西

node -r ts-node/register --inspect-brk xxx.ts: 加上--inspect-brk就可以用Chrome 開(kāi)發(fā)者工具來(lái)調(diào)試 Node 程序;不加--inspect-brk就直接運(yùn)行在終端里;
這時(shí)直接打開(kāi)一個(gè)控制臺(tái),等一下,就會(huì)看到左邊出現(xiàn)nodejs的logo,點(diǎn)擊它,得到圖1,已經(jīng)翻譯成js代碼了;

圖1.png

AST.png

圖2.png

圖3.png

根據(jù)上面幾張圖,我們可以大概知道AST是怎么來(lái)存儲(chǔ)值的了;

把let變成var

import { parse } from '@babel/parser';
import traverse from '@babel/traverse';
import generate from '@babel/generator';

const code = `let a = 'let'; let b = 5;`
const ast = parse(code, {sourceType: 'module'})  //這一步會(huì)得到一個(gè)AST

traverse(ast, {
    enter: item => {
        if(item.node.type === 'VariableDeclaration'){
            if(item.node.kind === 'let'){
                item.node.kind = 'var'
            }
        }
    }
})

const result = generate(ast, {}, code)
console.log(result.code);
image.png

這時(shí)我們?cè)倏磒arse>traverse>generate這三步,大概就明白是什么意思了;

那可以把代碼自動(dòng)轉(zhuǎn)成es5嗎

答:當(dāng)然可以,使用@babel/core@babel/preset-env 即可

  • 上面我們把let變成var是通過(guò)@babel/traverse的traverse先對(duì)AST進(jìn)行遍歷修改,再通過(guò)@babel/generator的generate把修改后的AST變成代碼;
  • 這次試驗(yàn)中,我們就不單獨(dú)使用@babel/traverse@babel/generator了,我們使用@babel/core,它里面包含了traverse和generate的功能;
  • @babel/preset-env的功能是把代碼從es6變成es5;
  • 下圖中babel.transformFromAstSync()可以把AST變成代碼,相當(dāng)于traversegenerate兩個(gè)步驟了;
import { parse } from '@babel/parser';
import * as babel from '@babel/core';
import * as fs from 'fs';

const code = fs.readFileSync('./test.js').toString()
const ast = parse(code, {sourceType: 'module'})  //這一步會(huì)得到一個(gè)AST
const result = babel.transformFromAstSync(ast, code, {
    presets: ['@babel/preset-env']
})

fs.writeFileSync('./test.es5.js', result.code)

分析index.js中的依賴

  • 怎么去識(shí)別import呢,通過(guò)AST的item.node.type === 'ImportDeclaration'

遞歸地分析嵌套依賴

總結(jié)

AST相關(guān)

1、parse:把代碼變成AST;
2、traverse:遍歷AST進(jìn)行修改;
3、generate:把AST變成代碼2;

工具

使用babel可以把一些高級(jí)代碼翻譯成es5

  • @babel/parser
  • @babel/traverse
  • @babel/generator
  • @babel/core 它包含前面三個(gè)
  • @babel/preset-env 內(nèi)置了很多規(guī)則

代碼技巧

  • 使用哈希表來(lái)存儲(chǔ)數(shù)據(jù)(哈希表是數(shù)據(jù)結(jié)構(gòu)中的術(shù)語(yǔ),在JS中一個(gè)對(duì)象可以看成是一個(gè)哈希表);
  • 通過(guò)檢測(cè)key來(lái)避免重復(fù)記錄依賴;

循環(huán)依賴

  • 循環(huán)依賴就是a.js引用了b.js,b.js又引用了a.js,就這么一直循環(huán)下去....
  • 有的循環(huán)依賴可以正常執(zhí)行;
  • 有的循環(huán)依賴不可以;
  • 但是都可以做靜態(tài)分析(靜態(tài)分析:不需要執(zhí)行代碼,只去做字面上的分析);
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容