TypeScript Compiler API:如何让自定义转换器在emit文件时生效
问题原因
你单独调用ts.transform得到的转换后AST,没有和program.emit流程关联。program.emit默认使用创建Program实例时解析生成的原始AST编译输出,完全没有用到你前置转换得到的结果。
解决方法
方法1:emit时直接传入转换器(推荐)
无需单独执行ts.transform,直接把你写的转换器传入emit方法的transformers配置项,TypeScript会在编译输出前自动应用转换:
import * as ts from "typescript"; const transformerFactory: ts.TransformerFactory<ts.Node> = context => rootNode => { function visit(node: ts.Node): ts.Node { node = ts.visitEachChild(node, visit, context); if (ts.isIdentifier(node)) return context.factory.createIdentifier(node.text + "suffix"); return node; } return ts.visitNode(rootNode, visit); }; const program = ts.createProgram(["source.ts"], {}) // 直接在emit参数中传入转换器配置 program.emit( undefined, undefined, undefined, undefined, { before: [transformerFactory] } );
方法2:手动写入转换后的内容
如果你已经完成了AST转换,也可以直接把打印出的转换结果手动写入目标文件,不需要走默认的emit输出流程:
import * as ts from "typescript"; import * as fs from "fs"; import * as path from "path"; const transformerFactory: ts.TransformerFactory<ts.Node> = context => rootNode => { function visit(node: ts.Node): ts.Node { node = ts.visitEachChild(node, visit, context); if (ts.isIdentifier(node)) return context.factory.createIdentifier(node.text + "suffix"); return node; } return ts.visitNode(rootNode, visit); }; const program = ts.createProgram(["source.ts"], {}) const sourceFile = program.getSourceFile("source.ts")! const transformationResult = ts.transform(sourceFile, [transformerFactory]) const transformedSourceFile = transformationResult.transformed[0]; const printer = ts.createPrinter(); const result = printer.printNode( ts.EmitHint.Unspecified, transformedSourceFile, sourceFile ); // 手动写入转换后的内容到js文件 fs.writeFileSync(path.resolve(__dirname, "source.js"), result);
两种方法都可以让最终输出的js文件和控制台打印的转换结果一致。
内容的提问来源于stack exchange,提问作者Daniel de Andrade Varela
相关产品推荐
相关产品推荐

