TypeScript: tsconfig

tsconfig 的继承与引用

https://stackoverflow.com/a/55000497/14602831
tsconfig 的 extends 与 reference 关系之前总是搞混。且对于使用的根本目的及涉及范围也不是很清晰。需要重新解释并记录。
tsc 会以 源文件 最近的 tsconfig.json 做作用域划分。所以无论是 eslint 中需要的 tsconfig,vscode 需要的 tsconfig,都可以通过为不同的 文件夹 定义不同的 tsconfig.json,来实现编译区分。
如:
src/components 文件夹中的 test.tsx 可以不引入 React 就实现 jsx 语法,因为 src/components 文件夹 中添加了独立的 tsconfig.json 文件:
image.png
image.png
而 src 下同样的 test.ts 则会报错,是因为 src 使用了最近的来自根目录的 tsconfig.json, jsx 配置不同:
image.png
image.png
同理,为 eslint 使用 ts-parser 后也就可以通过 不同的 tsconfig 来实现不同的处理效果了:
image.png

extends 用于继承 tsconfig 的内容,相当于配置共享,常见于项目根目录添加一个 tsconfig.json 用于通用配置设置,独立的文件夹中 extends baseconfig,且使用独立的 tsconfig.json,这样不同的文件夹中相当于不同的独立的 ts 项目。

  1. 项目结构
  2. /
  3. src/
  4. entity.ts # exports an entity
  5. tsconfig.json
  6. test/
  7. entity.spec.ts # imports an entity
  8. tsconfig.json
  9. tsconfig-base.json

reference 则用于引入地址的文件,相当于将某个独立项目引入到当前项目中。需与 compsite 配置配合使用:
Now, /src and /test folders basically hold two separate TypeScript projects with similar configuration. The last thing to do is to specify relation between the two. Since test depends on src, the test have to somehow “know” about src. This is done in two pretty obvious steps:

  • allowsrcto be “referenced” from the outside by declaring it as “composite”:

    1. // in /src/tsconfig.json
    2. {
    3. "extends": "../tsconfig-base.json",
    4. "compilerOptions": {
    5. // compiler options
    6. "composite": true
    7. }
    8. }
  • reference src from test:

    1. // in /test/tsconfig.json
    2. {
    3. "extends": "../tsconfig-base.json",
    4. "references": [
    5. { "path": "../src" }
    6. ]
    7. }

    The “include” array in /tsconfig-base.json is not needed now, since the code exclusion is done by “drawing new borders”.
    所以在 monorepo 中,其实是不需要 reference 的,因为 monorepo 肯定是先 build,这样包与包之间已经通过软链接建立引用关系了,且此时的引用也是来自 build 后的文件。
    reference 常用于 独立的 test文件夹(测试相关的ts) 引用 src 的内容(实际内容的ts)时,因为 test 的 tsconfig 通常与 src 的 config 会不同,这样分开管理分开配置也更合理一些。
    所以 reference 解决的不是 多项目 间的文件共享,而是 单项目 内,多配置间的文件共享,只是 tsconfig 会将其视为多项目,实则只是做编译区分。

tsconfig配置分离

另外如果有需要tsc直接编译产物的场景,可以先配置一个 tsconfig.json 作为开发中配置,供vscode,eslint使用,因为开发中可以默认为无需兼容的场景,不需要添加一些兼容类配置。也可以适当开启一些检测,然后在这份 config 的基础上,继承配置一个 tsconfig.build.json 或其他各种使用场景的配置,这样能够清晰一些:

  1. // tsconfig.json
  2. {
  3. "compilerOptions": {
  4. "allowJs": false,
  5. "target": "esnext",
  6. "module": "esnext",
  7. "moduleResolution": "Node",
  8. "esModuleInterop": false,
  9. "lib": [
  10. "esnext"
  11. ],
  12. "rootDir": ".",
  13. "baseUrl": ".",
  14. "newLine": "LF",
  15. "strict": true,
  16. "resolveJsonModule": true,
  17. "noUnusedLocals": true,
  18. "noUnusedParameters": true,
  19. "noImplicitReturns": true,
  20. "noFallthroughCasesInSwitch": true,
  21. "forceConsistentCasingInFileNames": true,
  22. "noEmit": true,
  23. },
  24. "exclude": [
  25. "node_modules",
  26. "temp"
  27. ],
  28. "include": [
  29. "src/**/*.ts",
  30. "typings/index.d.ts"
  31. ]
  32. }
  33. // tsconfig.build.json
  34. {
  35. "extends": "./tsconfig.json",
  36. "compilerOptions": {
  37. "target": "es2015",
  38. "module": "commonjs",
  39. "noEmit": false,
  40. "downlevelIteration": true,
  41. "importHelpers": true,
  42. "sourceMap": true,
  43. },
  44. "exclude": [
  45. "node_modules",
  46. "**/*/test.ts"
  47. ],
  48. }

Cannot find name ..

image.png
这类错都是因为缺少 类型文件。
如果此处的文件确实是运行在浏览器端,可以在 lib 中添加 dom,如果不是,最好添加 对应的 type,像此处只会在 node 中运行,添加 @types/node 即可,global 或 添加为 devdependencies 都可以。