babel
babel的原理
1、parse:把代码变成AST
2、traverse:遍历AST进行修改;
3、generate:把AST变成代码2
看下AST到底是什么东西
node -r ts-node/register --inspect-brk xxx.ts
: 加上--inspect-brk
就可以用Chrome 开发者工具来调试 Node 程序;不加--inspect-brk
就直接运行在终端里;
这时直接打开一个控制台,等一下,就会看到左边出现nodejs的logo,点击它,得到图1,已经翻译成js代码了;
AST.png
图2.png
图3.png
根据上面几张图,我们可以大概知道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这三步,大概就明白是什么意思了;
那可以把代码自动转成es5吗
答:当然可以,使用@babel/core
和 @babel/preset-env
即可
- 上面我们把let变成var是通过
@babel/traverse
的traverse先对AST进行遍历修改,再通过@babel/generator
的generate把修改后的AST变成代码; - 这次试验中,我们就不单独使用
@babel/traverse
和@babel/generator
了,我们使用@babel/core
,它里面包含了traverse和generate的功能; -
@babel/preset-env
的功能是把代码从es6变成es5; - 下图中
babel.transformFromAstSync()
可以把AST变成代码,相当于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'
递归地分析嵌套依赖
总结
AST相关
1、parse:把代码变成AST;
2、traverse:遍历AST进行修改;
3、generate:把AST变成代码2;
工具
使用babel可以把一些高级代码翻译成es5
- @babel/parser
- @babel/traverse
- @babel/generator
- @babel/core 它包含前面三个
- @babel/preset-env 内置了很多规则
代码技巧
- 使用哈希表来存储数据(哈希表是数据结构中的术语,在JS中一个对象可以看成是一个哈希表);
- 通过检测key来避免重复记录依赖;
循环依赖
- 循环依赖就是a.js引用了b.js,b.js又引用了a.js,就这么一直循环下去....
- 有的循环依赖可以正常执行;
- 有的循环依赖不可以;
- 但是都可以做静态分析(静态分析:不需要执行代码,只去做字面上的分析);
网友评论