如何使用TypeScript编译器API通过代码内容而非文件名创建Program
可以实现,核心思路是自定义 TypeScript 编译器的 CompilerHost 实例,接管文件读取、存在性校验逻辑,直接返回内存中存储的代码内容,无需依赖本地磁盘的真实文件。
注意你还是需要传入一个虚拟文件名作为ts.createProgram的第一个参数,该文件不需要真实存在,仅需要配置正确的后缀名(比如.ts/.tsx),用于 TypeScript 识别语法规则、执行模块解析逻辑。
具体实现步骤如下:
- 预先定义内存代码映射表,用虚拟文件名作为键,实际代码内容作为值
- 基于 TypeScript 默认的 CompilerHost 覆写必要方法,优先处理你定义的虚拟文件:
fileExists:如果查询的是虚拟文件名,直接返回truereadFile:如果查询的是虚拟文件名,直接返回对应的代码字符串getSourceFile:如果查询的是虚拟文件名,直接调用ts.createSourceFile生成源文件实例返回
- 将自定义的 CompilerHost 作为
ts.createProgram的第三个参数传入,即可完成 Program 实例创建
代码示例:
import * as ts from "typescript"; // 定义内存中的代码,虚拟文件名可以任意取,只要后缀符合要求 const virtualFilePath = "virtual-file.ts"; const codeContent = `const msg: string = "hello world"; console.log(msg);`; const memoryFiles = { [virtualFilePath]: codeContent }; // 自定义CompilerHost const compilerOptions = {}; const defaultHost = ts.createCompilerHost(compilerOptions); const customHost: ts.CompilerHost = { ...defaultHost, fileExists: (fileName: string) => { if (fileName in memoryFiles) return true; return defaultHost.fileExists(fileName); }, readFile: (fileName: string) => { if (fileName in memoryFiles) return memoryFiles[fileName]; return defaultHost.readFile(fileName); }, getSourceFile: (fileName: string, languageVersion: ts.ScriptTarget) => { if (fileName in memoryFiles) { return ts.createSourceFile( fileName, memoryFiles[fileName], languageVersion ); } return defaultHost.getSourceFile(fileName, languageVersion); } }; // 创建Program,直接传虚拟文件名即可 const program = ts.createProgram([virtualFilePath], compilerOptions, customHost);
如果你的代码完全不需要依赖任何外部的真实文件、第三方类型声明,可以继续覆写getDefaultLibFileName、resolveModuleNames等方法,完全脱离磁盘文件依赖。
内容的提问来源于stack exchange,提问作者Zachiah
相关产品推荐
相关产品推荐

