[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.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源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