如何在Vite插件中读取TypeScript文件的指定导出const?
解决Vite插件中读取TypeScript文件导出const的问题
你遇到的核心问题是:configureServer中的代码运行在Node.js环境,Node本身不支持直接导入TypeScript文件,Vite仅自动转译配置文件的TS代码,但不会处理插件里的动态TS导入。以下是两种可行的解决方案:
方案一:用ESBuild转译TypeScript内容
ESBuild是Vite默认的TS转译工具,直接用它处理目标文件内容,转译为Node可执行的JS代码后获取导出的schema:
import * as esbuild from 'esbuild'; import { readFile } from 'fs/promises'; import { PluginOption } from 'vite'; type zodToJsonSchemaOptions = { input: string; output?: string; }; const zodToJsonSchema = ({ input, output = "dist" }: zodToJsonSchemaOptions): PluginOption => { return { name: "vite-plugin-zod-to-json-schema", async configureServer(server) { const { watcher } = server; watcher.add(input); watcher.on("change", async (path) => { if (path.endsWith("features.ts")) { // 读取TS文件原始内容 const content = await readFile(path, 'utf8'); // 用ESBuild转译为CommonJS格式的JS const transformResult = await esbuild.transform(content, { loader: 'ts', format: 'cjs', }); // 创建临时模块环境执行转译后的代码 const tempModule = { exports: {} }; eval(`(function(module, exports) { ${transformResult.code} })(tempModule, tempModule.exports)`); // 获取目标导出的schema const targetSchema = tempModule.exports.schema; // 这里可添加schema的后续处理逻辑 console.log('获取到的schema:', targetSchema); } }); }, }; };
方案二:利用Vite模块图获取已编译模块
Vite开发服务器会维护模块图(moduleGraph),其中包含所有已编译处理的模块,直接从中读取目标文件的导出更贴合Vite运行机制:
import { PluginOption } from 'vite'; type zodToJsonSchemaOptions = { input: string; output?: string; }; const zodToJsonSchema = ({ input, output = "dist" }: zodToJsonSchemaOptions): PluginOption => { return { name: "vite-plugin-zod-to-json-schema", async configureServer(server) { const { watcher, moduleGraph } = server; watcher.add(input); // 预加载模块,确保模块图中有记录 await server.transformRequest(input); watcher.on("change", async (path) => { if (path.endsWith("features.ts")) { // 清除旧模块缓存,确保获取最新内容 const targetModule = moduleGraph.getModuleById(path); if (targetModule) moduleGraph.invalidateModule(targetModule); // 重新获取编译后的模块 const updatedModule = await server.transformRequest(path); if (updatedModule?.module) { const targetSchema = updatedModule.module.exports.schema; // 后续处理逻辑 console.log('获取到的schema:', targetSchema); } } }); }, }; };
注意事项
- 方案一的
eval需注意安全风险,仅适用于处理可信文件; - 方案二更推荐,能复用Vite的缓存与编译逻辑,避免重复转译;
- 确保
input为绝对路径或Vite可正确解析的路径,避免模块查找失败。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

