How to use multiple tsconfig files in vs-code?
TypescriptVisual Studio-CodeTsconfigTypescript Problem Overview
I am using Visual Studio Code and have a fairly common project structure:
├── client/
│ ├── tsconfig.json
├── shared/
├── server/
│ ├── tsconfig.json
├── project.json
The two tsconfig files have different settings (e.g. the one under client/
targets ES5, the one under server/
targets ES6). Note that there is no tsconfig in the root directory.
The problem is that I want the shared directory to be included in both projects. I can't do this using tsconfig because the exclude
option won't let me include a folder that is in a higher directory than the tsconfig.json, and using files
I have to constantly keep the list of files up to date as it doesn't support globs.
Note that I can compile fine by adding the shared folder into tsc, what I want is for the Visual Studio Code IDE to recognise the shared code for intellisense etc.
Is the only option to wait for filesGlob?
Typescript Solutions
Solution 1 - Typescript
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
Solution 2 - Typescript
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
whereas backend code generally does not.
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)
tsconfig.json
Backend 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/**/*"]
}
tsconfig.json
Frontend 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,
}),
...
],
...
};
Solution 3 - Typescript
I answered this here: tsconfig extension answer
The gist of the answer:
you can do this by extending your base tsconfig.json file:
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
}
}
Solution 4 - Typescript
As another variant, bind npm
command with next run:
{
'start': '...',
'buildFront': 'tsc -p tsconfig.someName.json'
}
Solution 5 - Typescript
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