You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过TypeScript Compiler API在编译时添加导入语句?

如何用TypeScript Compiler API在编译代码中添加导入语句

要实现这个需求,核心是修改TypeScript的抽象语法树(AST),再用Printer输出修改后的AST。以下是两种可行的实现方式:

方法一:直接修改单个源文件并输出

如果只是处理单个文件并生成目标代码,可以直接解析源文件、修改AST后打印:

import * as ts from 'typescript';

// 1. 读取并解析源文件为AST
const sourceCode = `// index.ts
export * from './user.repository'`;
const sourceFile = ts.createSourceFile(
  'index.ts',
  sourceCode,
  ts.ScriptTarget.Latest,
  true
);

// 2. 创建需要添加的导入节点
const createImportNode = (modulePath: string) => ts.factory.createImportDeclaration(
  undefined,          // 修饰符(如export)
  undefined,          // 导入子句(如import { xxx })
  ts.factory.createStringLiteral(modulePath), // 模块路径
  undefined           // 断言子句
);

const saveImport = createImportNode('./save.user.repository.extension');
const deleteImport = createImportNode('./delete.user.repository.extension');

// 3. 构造新的语句数组:把新导入放在最前面,拼接原文件语句
const updatedStatements = [saveImport, deleteImport, ...sourceFile.statements];

// 4. 生成修改后的源文件(TS AST不可变,必须创建新对象)
const updatedSourceFile = ts.factory.updateSourceFile(
  sourceFile,
  updatedStatements,
  sourceFile.isDeclarationFile,
  sourceFile.referencedFiles,
  sourceFile.typeReferenceDirectives,
  sourceFile.hasNoDefaultLib,
  sourceFile.libReferenceDirectives
);

// 5. 打印修改后的AST
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
const outputCode = printer.printFile(updatedSourceFile);
console.log(outputCode);

方法二:在编译流程中用自定义Transformer批量处理

如果需要在tsc编译过程中自动为指定文件添加导入,可通过自定义Transformer扩展编译流程:

import * as ts from 'typescript';

// 定义自定义Transformer:仅处理目标文件
function addImportsTransformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile> {
  return (context) => {
    return (sourceFile) => {
      // 只处理index.ts文件,避免全局修改
      if (sourceFile.fileName.endsWith('index.ts')) {
        const createImportNode = (modulePath: string) => ts.factory.createImportDeclaration(
          undefined,
          undefined,
          ts.factory.createStringLiteral(modulePath),
          undefined
        );
        const newImports = [
          createImportNode('./save.user.repository.extension'),
          createImportNode('./delete.user.repository.extension')
        ];
        // 更新语句数组并返回新的源文件
        const updatedStatements = [...newImports, ...sourceFile.statements];
        return ts.factory.updateSourceFile(sourceFile, updatedStatements);
      }
      // 其他文件直接返回原AST
      return sourceFile;
    };
  };
}

// 通过Compiler API启动编译并应用Transformer
const compilerOptions = { target: ts.ScriptTarget.Latest, module: ts.ModuleKind.CommonJS };
const program = ts.createProgram(['index.ts'], compilerOptions);
const emitResult = program.emit(undefined, undefined, undefined, undefined, {
  before: [addImportsTransformer(program)] // 编译前应用Transformer
});

// 输出编译错误(如果有)
if (emitResult.emitSkipped) {
  const diagnostics = [...ts.getPreEmitDiagnostics(program), ...emitResult.diagnostics];
  diagnostics.forEach(d => {
    const msg = ts.flattenDiagnosticMessageText(d.messageText, '\n');
    console.error(`${d.file?.fileName || 'unknown'}:${d.start || 0}:${d.length || 0} - ${msg}`);
  });
}

你之前用ts.createPrinter失败的原因

你直接打印了未修改的原AST,没有先通过updateSourceFile生成包含新导入节点的AST,所以输出内容和原代码一致。必须先修改AST结构,再打印修改后的版本。

内容的提问来源于stack exchange,提问作者danixl30 ct

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:23:35