TypeScript config 文件中的 extends
extends 的作用是继承另外的一个配置文件,对继承的配置文件进行合并或覆盖。例如:在一个项目中有多个页面,每个页面的 ts 配置文件希望做一些特殊的配置。可以采用上面的 extends 来实现。
在设计 extends 的时候,我们应该进行依赖反转的设计,将依赖关系放到每个页面维度处理,而不是放在公共的配置文件中进行处理。
举例说明:
一个功能包含 A、B 两个页面,A、B 希望在构建时让 tsc 处理自己实际依赖的文件,这里处理实际依赖的文件有一个前提条件,每个页面的结构较为稳定。
component
A
B
pages
A
B
pages/A 导入来 component/A,如何让 tsc 能只处理 pages/A 呢?
1.设置两个 tsconfig.json 文件,通过 include 来进行配置
设置多个 config 文件的方案维护起来比较麻烦,而且新增或删减都需要手工进行维护。但它也有一定的好处,可以应用灵活的配置。
在上述稳定结构的支撑下,是否可以将多个 config 文件的方案进行简化呢?
简化的含义是什么?这里的简化主要包含:从多个配置文件减少到一个或两个,从手动维护差异点改为自动化处理。最关键的点是差异管理。
好在 ts 提供了 extends 支持继承,这样可以将公共配置提取到 base config 中,同时借助 npm scripts 的能力,在 tsc 命令执行之前修改 tsconfig 文件为对应的项目配置文件。
例如提取如下公共配置
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"baseUrl": ".",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"noImplicitAny": true,
"removeComments": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"paths": {
"@/*": ["../src/*"]
}
},
"include": ["src"],
"exclude": ["node_modules", "build", "public", "postcss.config.js"]
}
差异化配置:
{
"extends": "./configs/tsconfig.base",
"include": [
"typings",
"src/utils",
"src/api/common",
"src/components/common",
"src/pages/${page}",
"src/components/${page}"
]
}
其中 paths 的路径是相对于 base config 文件的。
在项目中会引入其他人或组织开发的库,而且有些库并未支持 ts,所以需要在项目中对这些库增加 d.ts 。增加的 d.ts 需要在 include 的范围内,否则在编译过程中会提示找不到类型。