monorepo结构下tsconfig配置

#工程化#internal

需求背景(组件库举例

组件库分成组件部分(packages)和展示部分(play),还有将来的测试部分(tests)。
测试和展示部分都是依赖组件部分的,但测试和展示部分是没有关联,所以测试或展示任何一部分发生了改变,应该只编译发生改变的部分,另外没有发生变化的部分不应该进行编译才对。
那么通过 tsconfig.json 文件的顶级属性"references",就可以将我们的组件库再进行划分,从而变得更加的合理和编译性能的进一步提升。

组件库

tsconfig.json

{
  "files": [],
  "references": [
    { "path": "./tsconfig.web.json" }, // 组件包部分
    { "path": "./tsconfig.play.json" }, // 组件 play 部分
    { "path": "./tsconfig.vitest.json" } // 组件测试部分
  ]
}

"files": [] 表示这个配置文件本身不直接编译任何文件。
"references" 数组列出了其他TypeScript项目的路径。每个路径都指向一个独立的TypeScript配置文件。
在这种配置中,根目录的tsconfig.json文件实际上并不直接编译任何文件, 而是作为一个中央配置文件,用于组织和管理多个相关的TypeScript项目。

各个路径tsconfig.json

tsconfig.base.json
{
  "compilerOptions": {
    "outDir": "dist",
    "target": "es2018",
    "module": "esnext",
    "baseUrl": ".",
    "sourceMap": false,
    "moduleResolution": "node",
    "allowJs": false,
    "strict": true,
    "noUnusedLocals": true,
    "resolveJsonModule": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "removeComments": false,
    "rootDir": ".",
    "types": [],
    "paths": {
      "@element-plus/*": ["packages/*"],
      "element-plus": ["packages/element-plus"]
    },
    "preserveSymlinks": true
  }
}

tsconfig.node.json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "composite": true,
    "lib": ["ESNext"],
    "types": ["node"],
    "skipLibCheck": true
  },
  "include": [
    "internal/**/*",
    "internal/**/*.json",
    "scripts/**/*",
    "packages/theme-chalk/*",
    "packages/element-plus/version.ts",
    "packages/element-plus/package.json"
  ],
  "exclude": ["**/__tests__/**", "**/tests/**", "**/dist"]
}
tsconfig.play.json
{
  "extends": "./tsconfig.web.json",
  "compilerOptions": {
    "allowJs": true,
    "lib": ["ESNext", "DOM", "DOM.Iterable"]
  },
  "include": [
    "packages",
    "typings/global.d.ts",
    "typings/env.d.ts",

    // playground
    "play/main.ts",
    "play/env.d.ts",
    "play/src/**/*"
  ]
}

tsconfig.vite-config.json
{
  "extends": "./tsconfig.node.json",
  "compilerOptions": {
    "composite": true,
    "types": ["node"]
  },
  "include": ["**/vite.config.*", "**/vitest.config.*", "**/vite.init.*"],
  "exclude": ["docs"]
}

tsconfig.vitest.json
{
  "extends": "./tsconfig.web.json",
  "compilerOptions": {
    "composite": true,
    "lib": ["ES2021", "DOM", "DOM.Iterable"],
    "types": ["node", "jsdom", "unplugin-vue-macros/macros-global"],
    "skipLibCheck": true
  },
  "include": ["packages", "vitest.setup.ts", "typings/env.d.ts"],
  "exclude": ["node_modules", "dist", "**/*.md"]
}


tsconfig.web.json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "composite": true,
    "jsx": "preserve",
    "lib": ["ES2018", "DOM", "DOM.Iterable"],
    "types": ["unplugin-vue-macros/macros-global"],
    "skipLibCheck": true
  },
  "include": ["packages", "typings/env.d.ts"],
  "exclude": [
    "node_modules",
    "**/dist",
    "**/__tests__/**/*",
    "**/gulpfile.ts",
    "**/test-helper",
    "packages/test-utils",
    "**/*.md"
  ]
}

tsconfig的属性

extends

1 继承基础配置:

  • 允许一个配置文件继承另一个配置文件的设置。
  • 可以创建一个基础配置,然后在其他配置文件中扩展或覆盖这些设置。

2 减少重复:

  • 允许一个配置文件继承另一个配置文件的设置。
  • 可以创建一个基础配置,然后在其他配置文件中扩展或覆盖这些设置。

3 模块化配置:

  • 可以将配置分解成多个小的、专门的配置文件。
  • 根据不同的项目需求或构建目标组合这些配置。

4 覆盖继承的设置:

  • 在扩展配置中,可以覆盖或修改从基础配置继承的任何设置。

include

用途:指定哪些文件或目录应该被TypeScript编译器包含在编译过程中。

exclude

用途:指定哪些文件或目录应该被TypeScript编译器排除在编译过程之外。

compilerOptions的composite

这个选项设置为 true 之后,TypeScript 就会进行增量编译,所谓增量编译指的是生成 .d.ts 和 .tsbuildinfo 文件,其中 .tsbuildinfo 文件的内容就是记录所编译的项目的文件信息,主要是记录每个文件的 hash 值,下一次编译的时候,就会对比每个文件的 hash 值,如果没有变化那么就不进行编译,从而实现了编译性能的优化。

vue-vben-admin的tsconfig设计

在internal配置好各种场景下不同的ts配置,使用package.json的files字段把所配置的json包括起来。把tsconfig子仓下载到根仓库下,当app子仓这种仓库需要配置时,导入即可

参考