重要!中大型TS项目提升编译效率的简洁方案

765 阅读3分钟

随着应用的增长,TSC对代码做类型检查和编译所用的时间越来越长,本地开发编译时间增多严重拖慢开发效率。 解决这个时间消耗过大的问题,小墨找到了TSC内置了一个“项目引用”(project references)的功能,使用这个功能可以明显减少编译时间。 如果你的项目文件过多,建议使用“项目引用”功能。

项目引用的流程:

步骤1. 把一个 TypeScript项目分成多个子项目

一个子项目放在一个文件夹中,该文件夹中有一个tsconfig.json文件和一些TypeScript文件。 拆分项目时,应该把可能一起更新的代码放在同一文件夹中。

步骤2: 在各个子项目中创建并且配置tsconfig.json文件:

{
    "compilerOptions": {
        "composite": true,
        "declaration": true,
        "declarationMap": true,
        "rootDir": "."
    },
    "include": [
        "./**/*.ts"
    ],
    "references": [
        {
            "path": "./myReferencedProject",
            "prepend": true
        }
    ]
}

配置项说明:

  • composite: 告诉TSC,这个文件夹是一个大型 TypeScript项目的子项目。

  • declaration: 告诉TSC,为这个子项目生成.d.ts声明文件。

在项目引用中,子项目可以访问各子项目的声明文件和生成的 JavaScript,但是不能访问TypeScript源文件。
这就划定了一条界限,TSC不会再重新检查和编译代码:
如果更新了子项目A中的一行代码,TSC不会对子项目B重新做类型检查和编译;
TSC所要做的只是检查B的类型声明中有没有类型错误。
这个行为是项目引用在重新构建大型项目耗时较少的关键。
  • declarationMap: 告诉TSC,为生成的类型声明构建源码映射。

  • references: 在一个数组中列出该子项目依赖的其他子项目。

每个引用的path字段指向一个内有tsconfig.json文件的文件夹;
或直接指向一个TSC配置文件(如果配置文件的名称不是tsconfig.json)。
prepend 字段指明把引用的子项目生成的JavaScript和源码映射与当前子项目生成的JavaScript和源码映射拼接在一起。
注意,prepend只在使用outFile时有用;如未使用outFile, 可以不设置prepend
  • rootDir: 明确指明该子项目应该相对根项目(.)编译。
另一种是设置outDir,指明根项目的outDir中的一个子文件夹。

步骤3.在根文件见中创建一个tsconfig.json文件

引用没有被其他子项目引用的子项目:

{
    "files": [],
    "references": [
        {"path": "./myProject"},
        {"path": "./mySencondProject"}
    ]
}

步骤4. 使用TSC编译项目时,通过build标志让TSC把项目引用考虑进来

 tsc --build #或者简写为 tsc -b

完成上面几个步骤,就能实现项目引用了。

最后 编写可复用的tsconfig配置

如果所有的子项目配置项都是一样的,就可以把选项抽离到顶层tsconfig,这样可以减少一些重复配置。 根目录下创建tsconfig.json维护公共的配置选项,再让子项目的tsconfig.json做扩展。

// 根目录tsconfig.json
{
  "compilerOptions": {
    "composite": true,
    "declaration": true,
    "declarationMap": true,
    "lib": ["es2015", "es2016.array.include"],
    "rootDir": ".",
    "sourceMap": true,
    "strict": true,
    "target": "es5"
  }
}

//子项目tsconfig.json,使用 extends选项扩展:
{
    "extends": "../tsconfig.base",
    "include": [
        "./**/*.ts"
    ],
    "references": [
        {
            "path": "../myReferencedProject",
            "prepend": true
        }
    ]
}

结语

小墨也是在做公司项目过程中,随着代码量的增大,编译时间等待越来越久,所以查阅资料找到这个方案,实现方式不是很复杂,分享出来希望能帮到小伙伴们,大家一起加油~