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 開發(fā)者工具來調(diào)試 Node 程序臀栈;不加--inspect-brk
就直接運(yùn)行在終端里;
這時直接打開一個控制臺挠乳,等一下权薯,就會看到左邊出現(xiàn)nodejs的logo,點(diǎn)擊它睡扬,得到圖1盟蚣,已經(jīng)翻譯成js代碼了;
圖1.png
AST.png
圖2.png
圖3.png
根據(jù)上面幾張圖卖怜,我們可以大概知道AST是怎么來存儲值的了屎开;
把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'}) //這一步會得到一個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
這時我們再看parse>traverse>generate這三步,大概就明白是什么意思了马靠;
那可以把代碼自動轉(zhuǎn)成es5嗎
答:當(dāng)然可以奄抽,使用@babel/core
和 @babel/preset-env
即可
- 上面我們把let變成var是通過
@babel/traverse
的traverse先對AST進(jìn)行遍歷修改,再通過@babel/generator
的generate把修改后的AST變成代碼甩鳄; - 這次試驗中逞度,我們就不單獨(dú)使用
@babel/traverse
和@babel/generator
了,我們使用@babel/core
妙啃,它里面包含了traverse和generate的功能档泽; -
@babel/preset-env
的功能是把代碼從es6變成es5; - 下圖中
babel.transformFromAstSync()
可以把AST變成代碼揖赴,相當(dāng)于traverse
和generate
兩個步驟了茁瘦;
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'}) //這一步會得到一個AST
const result = babel.transformFromAstSync(ast, code, {
presets: ['@babel/preset-env']
})
fs.writeFileSync('./test.es5.js', result.code)
分析index.js中的依賴
- 怎么去識別import呢,通過AST的
item.node.type === 'ImportDeclaration'
遞歸地分析嵌套依賴
總結(jié)
AST相關(guān)
1储笑、parse:把代碼變成AST甜熔;
2、traverse:遍歷AST進(jìn)行修改突倍;
3腔稀、generate:把AST變成代碼2盆昙;
工具
使用babel可以把一些高級代碼翻譯成es5
- @babel/parser
- @babel/traverse
- @babel/generator
- @babel/core 它包含前面三個
- @babel/preset-env 內(nèi)置了很多規(guī)則
代碼技巧
- 使用哈希表來存儲數(shù)據(jù)(哈希表是數(shù)據(jù)結(jié)構(gòu)中的術(shù)語,在JS中一個對象可以看成是一個哈希表)焊虏;
- 通過檢測key來避免重復(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