如何在 vs-code 中使用多个 tsconfig 文件?

我使用的是 VisualStudio 代码,并且有一个相当常见的项目结构:

├── client/
│   ├── tsconfig.json
├── shared/
├── server/
│   ├── tsconfig.json
├── project.json

这两个 tsconfig 文件有不同的设置(例如,client/下的一个目标是 ES5,server/下的一个目标是 ES6)。注意,根目录中没有 tsconfig。

问题是,我希望两个项目都包含共享目录。我不能使用 tsconfig,因为 exclude选项不允许我包含比 tsconfig.json 目录更高的文件夹,而使用 files我必须不断更新文件列表,因为它不支持 globs。

注意,我可以通过将共享文件夹添加到 tsc 来编译,我想要的是 Visual Studio Code IDE 能够识别智能感知的共享代码等。

是等待 FilesGlob的唯一选择吗?

82139 次浏览

The new version of VSCode supports Typescript 2, add this adds support for globs in tsconfig.json with the include option. See http://www.typescriptlang.org/docs/handbook/tsconfig-json.html

I answered this here: tsconfig extension answer

The gist of the answer:

you can do this by extending your base tsconfig.json file:

tsconfig extension

just do not exclude directories in the base tsconfig.json and typescript should be able to resolve your typings for you (know this is true using node_modules/@types, or the typings module)

For example:

configs/base.json:

{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true
}
}

tsconfig.json:

{
"extends": "./configs/base",
"files": [
"main.ts",
"supplemental.ts"
]
}

tsconfig.nostrictnull.json:

{
"extends": "./tsconfig",
"compilerOptions": {
"strictNullChecks": false
}
}

As another variant, bind npm command with next run:

{
'start': '...',
'buildFront': 'tsc -p tsconfig.someName.json'
}

These days it is much easier as vscode has better support for this.

You can use this directory structure so all the code is independent:

├── frontend/
│   ├── src/
│   │   ├── <frontend code>
│   ├── package.json
│   ├── tsconfig.json
├── shared/
│   ├── package.json
├── backend/
│   ├── src/
│   │   ├── <backend code>
│   ├── package.json
│   ├── tsconfig.json

Then in both the backend and frontend tsconfig.json:

{
"compilerOptions": {
"paths": {
"~shared/*": ["../shared/*"]
},
"rootDirs": [
"./src",
"../shared"
]
}
}

To allow access to the shared code e.g.:

import { Foo } from '~shared/foo';

Old Answer

Use a single tsconfig.json for the root. And then extend it for each project (backend tsconfig.server.json, frontend tsconfig.webpack.json).

  • Root tsconfig.json include: ['src'] to ensure all files get typechecked in the IDE
  • Backend tsconfig.server.json exclude: ['src/app'] the frontend files
  • Frontend : tsconfig.webpack.json exclude: ['src/server'] the backend files

Folder Structure

├── src/
│   ├── app/    < Frontend
│   ├── server/ < Backend
│   ├── common/ < Shared
├── tsconfig.json
├── tsconfig.server.json
├── tsconfig.webpack.json

Config Files

tsconfig.json

{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true
},
"include": [
"src"
]
}

tsconfig.webpack.json

{
"extends": "./tsconfig.json",
"exclude": [
"src/app"
]
}

tsconfig.server.json

{
"extends": "./tsconfig.json",
"exclude": [
"src/server"
]
}

More

Example lesson

As others have mentioned, the existing answer does not solve the problem if the frontend and backend have different types - which is in nearly every case, as frontend code supports the DOM (and not the node.js standard library) whereas backend code supports the node.js standard library (and generally not the DOM).

Having a top level tsconfig.json would mean that dom code would show up as errors in frontend code (if dom is a lib) or that dom code would be allowed in backend code (if dom is omitted).

Here's a working solution:

Folder Structure

Our projects tend to be 'backend by default' with a specific folder for frontend code.

├── src/
│   ├── frontend/ < Frontend
│   │     ├── `tsconfig.json` (extends frontend framework defaults, eg Svelte)
│   ├── http/ < Backend
│   ├── events/ < Backend
├── tsconfig.json `tsconfig.json` (backend tsconfig)

Backend tsconfig.json

This is usually fairly minimal. We use jest for testing and the es2019 JS stdlib.

{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"outDir": "dist",
"moduleResolution": "node",
"esModuleInterop": true,
"lib": ["es2019"],
"types": ["jest"],
},
"exclude": [
"node_modules",
"public/*",
"src/frontend/*"
],
"include": ["src/**/*"]
}

Frontend tsconfig.json

This is for Svelte but would work similarly in older frameworks. The frontend has different types because it supports .svelte files and the dom

{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
// Default included above is es2017
"target": "es2019",
},
"lib": ["es2019", "dom"],
}

Frontend specific tools

Making rollup use a separate tsconfig file:


export default {
input: ...
output: ...
plugins: [
...
typescript({
tsconfig: "src/frontend/tsconfig.json",
sourceMap: isDevelopment,
inlineSources: isDevelopment,
}),
...
],
...
};