[Typescript] TypeScript Project References

Consider this package.json file:

{
  "name": "exercise",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "dev": "run-p dev:*",
    "dev:client": "tsc --project ./src/client/tsconfig.json --watch",
    "dev:server": "tsc --project ./src/server/tsconfig.json --watch"
  }
}

There are scripts for running the client and server TypeScript configurations, and a dev script runs both of them in parallel.

This is a lot of plumbing to get TypeScript to work. We would need to do the same for build scripts and any other scripts that involve TypeScript.

A better way to organize this is by using TypeScript project references.

 

Solution 1 (code)

In this solution, we have a new tsconfig.json file that has references to src/client/tsconfig.json and src/server/tsconfig.json. Unfortunately, there's no way to use wildcards in the references, so you have to manually list each tsconfig.json:

{
  "references": [
    {
      "path": "./src/client/tsconfig.json"
    },
    {
      "path": "./src/server/tsconfig.json"
    }
  ],
  "files": []
}

Note that there is also an empty files array. This is because the tsconfig.json file in the root directory is not responsible for type checking any files. Instead, it serves as a reference tsconfig.json to run the client and server tsconfig.json files in a specific order.

Inside of the package.json file, the dev script uses the -b flag. This tells TypeScript to run in build mode, which means it runs all the project references as well. This allows us to type check the entire repo with a single command:

// package.json
{
  "name": "exercise",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "dev": "tsc -b --watch"
  }
}

Inside of the tsconfig.base.json file, we've added the composite: true property. This enables constraints, allowing a TypeScript project to be used with project references. In other words, it tells TypeScript that this is a child project and needs to be run with project references.

// tsconfig.base.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "esModuleInterop": true,
    "noEmit": true,
    "strict": true,
    "skipLibCheck": true,
    "isolatedModules": true,
    "composite": true
  },
}

When TypeScript runs in build mode, it emits tsconfig.tsbuildinfo files, which are large and should not be committed to your repository. These files cache the results of type checking, which makes subsequent checks much faster.

To ignore these files, you can add *.tsbuildinfo to your root .gitignore file.

This first solution is an example of how you can organize your TypeScript configurations using project references.

However, there are several tsconfig files present in different directories.

 

Solution 2 (Code)

In this solution, we move all the tsconfig files to the root directory. This makes it clear that the tsconfig.json file belongs to the entire project, not just a specific package:

tsconfig.json
tsconfig.base.json
tsconfig.client.json
tsconfig.server.json

Inside of the tsconfig.client.json file, we can use the extends keyword to inherit the compiler options from tsconfig.base.json. Then, we can specify the include paths for the client packages:

// tsconfig.client.json

{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "lib": [
      "ES2022",
      "DOM",
      "DOM.Iterable"
    ]
  },
  "include": [
    "src/client"
  ]
}

The tsconfig.server.json configuration is similar, but won't include the DOM-related libraries:

{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "lib": [
      "ES2022"
    ]
  },
  "include": [
    "src/server"
  ]
}

Both of the client and server tsconfig files are referenced by the tsconfig.json file in the root directory:

{
  "references": [
    {
      "path": "./tsconfig.client.json"
    },
    {
      "path": "./tsconfig.server.json"
    }
  ],
  "files": []
}

This solution also works, but it can feel like a bit much to have four tsconfig files in the root directory.

 

Solution 3 (Code)

In this solution, we create a .config folder in the project root.

Inside of the .config directory we'll add the tsconfig.base.json file along with the tsconfig.client.json and tsconfig.server.json files.

Then inside of the root directory of the project, the tsconfig.json file will reference the other configurations.

This solution is becoming a more common pattern for storing configuration files.

 

Wrapping Up

Project references are a great feature for configuration. They allow for efficient organization and speed up type checking by caching the results. Whether you keep your configurations in the root directory, each package, or a separate configuration folder, choose what makes the most sense for your project's structure and complexity.

posted @   Zhentiw  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2022-09-04 [Go] Creating a slice with make
2022-09-04 [Go] Array
2022-09-04 [Go] Functions
2022-09-04 [Go] using For loop as While loop
2022-09-04 [Go] switch - fallthrough
2022-09-04 [Go] if - scoped variable
2022-09-04 [Go] Variables - non-declaration statement
点击右上角即可分享
微信分享提示