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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:42:43