How to use multiple tsconfig files in vs-code?

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 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)

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,
    }),
    ...
  ],
   ...
};