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

如何编程编译TypeScript项目引用并为每个项目传递独立编译选项

针对ts.createSolutionBuilder动态传递单项目编译选项的实现方案

核心思路

ts.createSolutionBuilder 支持自定义构建宿主来拦截配置读取逻辑,不需要依赖本地存储的tsconfig.json文件,你可以通过重写宿主的配置读取相关方法,为每个项目返回动态生成的编译配置。

实现步骤

  • 先维护全局的动态配置映射表,键为每个项目的根路径,值为该项目对应的tsconfig配置内容(可以是JSON字符串,也可以是解析后的ts.ParsedCommandLine对象)
  • 扩展官方提供的默认Solution Builder宿主,重写readFile、getModifiedTime方法,拦截tsconfig.json的读取请求,直接返回你预生成的对应项目的配置内容
  • 可选优化:重写readConfiguration方法直接返回解析完成的配置对象,省去JSON序列化/反序列化的性能开销

代码示例

import * as ts from "typescript";

// 动态配置映射:key为项目绝对路径,value为对应项目的tsconfig配置JSON
const projectConfigMap = new Map<string, string>([
  ["/workspace/packages/package-a", JSON.stringify({
    compilerOptions: {
      outDir: "./dist",
      rootDir: "./src",
      declaration: true
    },
    include: ["src/**/*"],
    references: [{ path: "../package-b" }]
  })],
  ["/workspace/packages/package-b", JSON.stringify({
    compilerOptions: {
      outDir: "./dist",
      rootDir: "./src",
      strict: false
    },
    include: ["src/**/*"]
  })]
]);

// 创建基础构建宿主
const host = ts.createSolutionBuilderHost(
  undefined,
  (err) => console.error(err),
  (log) => console.log(log)
);

// 重写文件读取方法,拦截tsconfig请求
const defaultReadFile = host.readFile;
host.readFile = (filePath: string) => {
  const normalizedPath = ts.normalizePath(filePath);
  for (const [projectRoot, configJson] of projectConfigMap) {
    const targetConfigPath = ts.normalizePath(ts.join(projectRoot, "tsconfig.json"));
    if (normalizedPath === targetConfigPath) {
      return configJson;
    }
  }
  return defaultReadFile(filePath);
};

// 重写修改时间查询,避免TS缓存不存在的配置文件状态
const defaultGetMtime = host.getModifiedTime;
host.getModifiedTime = (filePath: string) => {
  const normalizedPath = ts.normalizePath(filePath);
  for (const [projectRoot] of projectConfigMap) {
    const targetConfigPath = ts.normalizePath(ts.join(projectRoot, "tsconfig.json"));
    if (normalizedPath === targetConfigPath) {
      // 配置有更新时可返回最新时间戳,强制重新构建
      return new Date();
    }
  }
  return defaultGetMtime(filePath);
};

// 初始化构建器并执行构建
const builder = ts.createSolutionBuilder(host, ["/workspace/tsconfig.json"], { force: true });
const exitCode = builder.build();
console.log(`构建结束,退出码:${exitCode}`);

额外说明

你动态生成的每个项目配置中的references路径需要和映射表中的项目路径对应,保证TypeScript可以正确识别项目依赖顺序,不会出现依赖缺失的编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:54:04