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

120
我正在使用Visual Studio Code,项目结构相当普遍:

我正在使用Visual Studio Code,项目结构相当普遍:

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

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

问题在于我希望共享的文件夹包含在两个项目中。但是我无法使用 tsconfig 实现这一点,因为 exclude 选项不允许我包含比 tsconfig.json 更高目录层级的文件夹,并且使用 files 必须不断更新文件列表,因为它不支持通配符。

请注意,将共享文件夹添加到 tsc 中可以正常编译,但我希望 Visual Studio Code IDE 能够识别共享代码以获得智能提示等功能。

唯一的选择是等待 filesGlob 吗?


这个有用吗?https://www.npmjs.com/package/tsconfig-glob - michaelmesser
你可以随时使用 atom-typescript。 - michaelmesser
是的,我想我可以使用那个包来生成文件数组,但这很烦人,因为我必须一直让它保持更新状态。我很久以前就尝试过Atom(在VSC发布之前),但它非常慢且容易出错,不过也许现在已经改善了。 - Mike Jerred
Atom现在比以前好多了。atom-typescript是一个非常不错的包。 - michaelmesser
5个回答

109

现在使用vscode更容易实现这一点,因为它对此提供了更好的支持。

您可以使用此目录结构,以使所有代码都是独立的:

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

在后端和前端都需要修改tsconfig.json文件:

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

为了允许访问共享的代码,例如:

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

旧回答

在根目录下使用单个tsconfig.json文件,然后为每个项目扩展它(后端tsconfig.server.json,前端tsconfig.webpack.json)。

  • 根目录下的tsconfig.jsoninclude: ['src']以确保在IDE中对所有文件进行类型检查
  • 后端tsconfig.server.jsonexclude: ['src/app']排除前端文件
  • 前端:tsconfig.webpack.jsonexclude: ['src/server']排除后端文件

文件夹结构

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

配置文件

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"
  ]
}

更多

示例课程(由我制作)


14
如果这些目录具有冲突的类型,那么这种方法将无效。例如,Jest和Cypress都有自己的关键字describe的类型定义,如果在tsconfig.json中的types数组中包含了jest和cypress的类型,则会出现编译错误。而且,VS Code的智能感知该使用哪个类型定义也不清楚。这不是正确的答案。 - basickarl
1
如何使用扩展配置文件进行编译?在根目录下运行tsc似乎只适用于主配置文件。是否需要通过“tsc -p childTsConfig”进行编译? - Mikhail
6
注意:如果你扩展一个tsconfig文件,属性将被覆盖。例如,你不能向include数组添加内容,而是必须覆盖它。 - Drarig29
2
是的,你的回答很好,这只是给未来的读者的一个建议... 我以为扩展会添加到数组中,但事实并非如此。 - Drarig29
8
这并不能解决问题。VScode将使用tsconfig.json,因此在编辑这些文件时不会使用特定于前端/后端的配置。因此,当编辑前端文件时,VScode将显示警告,因为tsconfig.json不包括相关部分。 - mikemaccana
显示剩余5条评论

29

正如其他人提到的,现有的答案无法解决前端和后端类型不同的问题 - 几乎在每种情况下都是如此,因为前端代码支持DOM(而不是node.js标准库),而后端代码支持node.js标准库(通常不支持DOM)。

有一个顶级tsconfig.json将意味着dom代码将显示为前端代码中的错误(如果dom是lib),或者dom代码将被允许在后端代码中使用(如果省略dom)。

以下是一个可行的解决方案:

文件夹结构

我们的项目倾向于默认为“后端”,并具有用于前端代码的特定文件夹。

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

后端tsconfig.json

通常很简单。我们使用jest进行测试和es2019 JS标准库。

{
  "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

这是针对Svelte的,但在旧框架中也可以类似地使用。前端有不同的类型,因为它支持.svelte文件和dom

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

前端专属工具

使rollup使用独立的tsconfig文件:


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

这个处理共享代码吗?前端不会拉取与后端 tsconfig 编译的共享代码吗? - Joe Lapp
Rollup的“input”选项将确定前端代码的入口点。 Rollup只会包含由该入口点文件导入的文件(以及由这些导入导入的文件)。因此,您的前端捆绑包将仅包括前端代码。 - mikemaccana
好的。问题是,我有一些需要在前端和后端之间共享的代码,例如验证代码。前端进行验证以提供实时反馈,后端进行验证以防止有人绕过前端。我正在按照您所描述的方式设置事物,以查看是否可以实现这一点。 - Joe Lapp
1
@JoeLapp说得有道理,我经常使用这个配置来做这件事。因此,在前端导入所需的内容,包括共享代码。不要在前端导入后端特定的模块,只导入你想要共享的代码。 - mikemaccana
那么后端的tsconfig.json位于项目根目录?这对我来说似乎很奇怪;我想它可能与vscode的解决方法有关而不是编译器,但我想知道我是否错了。 - Daniel Kaplan

16
我在这里回答了: tsconfig extension answer 回答的要点是:
通过扩展您的基本 tsconfig.json 文件,您可以实现此目的。
请参阅以下链接以获取详细信息:tsconfig extension 只需不要在基本 tsconfig.json 中排除目录,TypeScript 就能够为您解析类型(使用 node_modules/@types 或 typings 模块可验证此操作是否有效)。
例如:
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
   }
}

10
您好,我该如何从命令提示符中调用编译器?我一直在调用基本的json文件,但它没有起作用。其他文件被忽略了。 - Everton Santos
7
IDE如何识别自定义的tsconfig.*.json文件?我该如何将不同目录下的tsconfig分开处理? - vintprox
这不是由IDE来识别多个tsconfigs的问题。你只需要通过 --project(别名:-p)选项将要使用的tsconfig传递给TypeScript编译器即可。 https://www.typescriptlang.org/docs/handbook/compiler-options.html - weagle08
示例代码 https://github.com/ozknemoy/node-ts-nodemon-starter/tree/ts-starter-app_3-tsconfigs - dimson d
这很酷,但是如果你想让 vscode 和 eslint 正确地对 jest.config.ts 和 somecomponent.ts 进行代码检查,其中 somecomponent.ts 依赖于 module="bundler",而 jest.config.ts 依赖于 "importJson" true... 你做不到。使用不同的扩展名是行不通的,因为 vscode 会加载基础的 tsconfig.json 文件来处理所有的文件。所以你必须将 jest.config.ts 移动到另一个项目中,并通过 tsconfig 项目引用来运行具有不同配置位置的命令行参数。 - Ryan Mann

5
作为另一种变体,将npm命令与下一个运行绑定:
{
   'start': '...',
   'buildFront': 'tsc -p tsconfig.someName.json'
}

2
为什么会是-1?他只是在解释你可以选择具体要使用的配置。这个问题有什么不对吗? - Rip3rs

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接