parser 的功能是把源码转成 AST,支持各种语法的 parse。
babel 的 parser 并不是从零自己实现的,而是基于 acron 做了扩展。在 《js parser 的历史》那一节大部分讲过 js parser 都是 estree 标准的,acorn 也是 estree 标准的实现,支持插件,

babel 实现了 jsx、typescript、flow 等语法插件的扩展,并且修改了一些 AST,比如 Literal 扩展为了 StringLitreal、NumericLiteral 等。
所以,我们也不会从零实现 parser,也会采用基于 acron 扩下扩展的方式。
# 思路分析
acorn 插件的实现方式是继承之前的 Parser 返回新的 Parser,重写一些方法来做 AST 修改和扩充。
比如:
module.exports = function(Parser) {
return class extends Parser {
parseLiteral (...args) {
const node = super.parseLiteral(...args);
switch(typeof node.value) {
case 'number':
node.type = 'NumericLiteral';
break;
case 'string':
node.type = 'StringLiteral';
break;
}
return node;
}
}
}
@前端进阶之旅: 代码已经复制到剪贴板
这是我们之前实现过的,把 Literal 扩展为 StringLiteral、NumericLiteral 等的一个插件。
之前还实现过扩展一个 guang 的关键字的插件。
我们希望提供这种 api:
const ast = parser.parse(sourceCode, {
plugins: ['literal', 'guangKeyword']
});
@前端进阶之旅: 代码已经复制到剪贴板
也就是根据传入的 plugins 来确定使用什么插件,然后返回扩展以后的 parser。实现方式就是保存一个插件的 map,按照传入的插件名使用就行。
# 代码实现
我们把插件放到不同的模块中,然后通过 map 来维护:
