引言
Project Reference
总结
引言TypeScript 给 JavaScript 添加了一套类型系统,可以在编译期间检查出类型错误,这增加了代码的健壮性,但也多了一个编译的过程。
ts 编译速度与项目规模有关,如果项目比较大,代码很多,那就需要编译很长一段时间。
有没有什么办法可以提升 tsc 编译的性能呢?
还真有,TypeScript 3.0 的时候实现了 Project Reference 的特性,就是用于优化编译和类型检查的性能的。
那 Project Reference 是干什么的呢?
Project Reference想象这样一个场景。项目目录下有两个相对独立的模块 aaa 和 bbb
它们是用同一个 tsconfig.json 来配置编译方式的:
执行 tsc 就会编译所有 include 的文件到 dist 目录下:
假设 aaa 和 bbb 都很大,编译要很久,但是两者的关联还不是特别大。
aaa 模块下的变动基本和 bbb 模块下的没啥关系,但是 aaa 变了,bbb 也要重新编译一遍,bbb 变了 aaa 也要重新编译一遍,这就很没必要。
有的同学说,那在 aaa 和 bbb 下分别放一个 tsconfig.json,各自编译各自的不就行了?
这样是可以,但是这样就是多次编译了,比较麻烦。
能不能还是一次编译,但是对一些相对独立的模块做下缓存,不要跟随别的模块一起编译呢?
可以的,这就是 Project Reference 做的事情了。
在 aaa 和 bbb 下各自创建一个 tsconfig.json,放各自的编译配置。注意这里要加一个 composite: true,这是 Project Reference 需要的:
然后在根目录的 tsconfig.json 里加上一个 references 的配置,引入 aaa 和 bbb:
这样再执行 tsc --build 进行编译,你会发现编译结果多了 .d.ts 的声明,还多了 tsconfig.tsbuildinfo 的文件:
打开 tsconfig.tsbuildinfo 看一下,会发现它记录了编译了哪些文件,还记录了这些文件的 hash 值:
看到这里,你是不是就知道为啥它能实现缓存了?
没错,就是对比文件的 hash,当编译到这个 project 的时候,会对比下 hash 有没有变化,变了才去编译。没变的就直接跳过了。
而且,别的地方可能用到这个 project 的类型,所以需要生成 d.ts 声明文件,这就是为啥我们没有指定 declaration: true 的配置,但是编译产物里还是有 d.ts。其实这是 composite 选项做的,它设置了 Project Reference 需要的一些编译选项:
现在当你修改了 aaa 下某个模块的代码,重新编译的时候就不会编译 bbb 了,只会编译 aaa 下的那个模块。
这就是 Project Reference 的作用。
当然,这种编译模式和常规的编译模式不同,所以不是直接用 tsc 来编译,而是用 tsc --build 或者 tsc -b。
此外,Project Reference 还支持通过 prepend 指定编译顺序,比如给 bbb 添加 prepend: true,那么就会先编译 bbb,再编译当前项目,然后编译 aaa:
其实很容易想到,monorepo 里就可以用 Project Reference 来提升 tsc 的编译性能。因为 monorepo 下的多个 project 相互之间都比较独立,一个模块的改动一般不会影响另一个模块,所以编译的时候也应该各自做缓存。
总结TypeScript 3.0 时实现了 Project Reference 来优化性能。
如果项目下有一些相对独立的模块,别的模块的变动不影响它,但是它却要跟着重新编译一次,这时就可以用 Project Reference 来优化了。
在独立的模块下添加 tsconfig.json,加上 composite 的编译选项,在入口的 tsconfig.json 里配置 references 引用这些独立的模块。然后执行 tsc --build 或者 tsc -b 来编译。
这时候就实现了编译和类型检查的性能优化。
原理是编译时会生成 tsconfig.tsbuildinfo 的文件,记录着编译的文件和它们的 hash,当再次编译的时候,如果文件 hash 没变,那就直接跳过,从而提升了编译速度。
这是 TypeScript 提供的编译性能优化机制,当项目比较大,tsc 执行的速度比较慢的时候,不妨尝试一下。
以上就是Project Reference优化TypeScript编译性能示例的详细内容,更多关于Project Reference优化tsc的资料请关注软件开发网其它相关文章!