这是 babel 解析的最后一篇,坚持就是胜利✌️。
在这篇中我会梳理下 babel 是如何需要借助 generator 方法将处理好的 AST 重新转化为代码,从而完成整个流程。
首先还是回到 babel-core 的 run 方法中,当执行 generateCode(config.passes, file) 方法时最终执行的下面的代码:
// babel-generator/src/index.ts
export default function generate(
ast: t.Node,
opts?: GeneratorOptions,
code?: string | {
[filename: string]: string },
): any {
const gen = new Generator(ast, opts, code);
// 🌵🌵🌵 执行这里 🌵🌵🌵
return gen.generate();
}
当调用 generate 时执行的是 Printer 中的 generate。
// Generator
generate() {
// 🌵🌵🌵 执行这里 🌵🌵🌵
return super.generate(this.ast);
}
// -------------我是快乐的分割线--------------
// Printer
generate(ast) {
// 🌵🌵🌵 执行这里 🌵🌵🌵
this.print(ast);
this._maybeAddAuxComment();
return this._buf.get();
}
然后将 ast 传入到实例上 print 方法中开始生成逻辑。
print(node, parent ?) {
if (!node) return;
const oldConcise = this.format.concise;
if (node._compact) {
this.format.concise = true;
}
const printMethod = this[node.type];
if (!printMethod) {
}
this._printStack.push(node);
const oldInAux = this._insideAux;
this._insideAux = !node.loc;
this._maybeAddAuxComment(this._insideAux && !oldInAux);
let needsParens = n.needsParens(node, parent, this._printStack);
if (
this.format.retainFunctionParens &&
node.type === "FunctionExpression" &&
node.extra &&
node.extra.parenthesized
) {
needsParens = true;
}
if (needsParens) this.token("(");
this._printLeadingComments(node);
const loc = t.isProgram(node) || t.isFile(node) ?