TypeScript 编译性能优化:Project Reference

TypeScript 给 JavaScript 添加了一套类型系统,可以在编译期间检查出类型错误,这增加了代码的健壮性,但也多了一个编译的过程。

ts 编译速度与项目规模有关,如果项目比较大,代码很多,那就需要编译很长一段时间。

有没有什么办法可以提升 tsc 编译的性能呢?

还真有,TypeScript 3.0 的时候实现了 Project Reference 的特性,就是用于优化编译和类型检查的性能的。

那 Project Reference 是干什么的呢?

Project Reference

想象这样一个场景。项目目录下有两个相对独立的模块 aaa 和 bbb

be513f79ecfea87597457c4b7a79e859.png

它们是用同一个 tsconfig.json 来配置编译方式的:

b407ff2e9e7638b30725db5a59fc6fa5.png

执行 tsc 就会编译所有 include 的文件到 dist 目录下:

86c048100ea4c34d8573017334dbdaaa.png

假设 aaa 和 bbb 都很大,编译要很久,但是两者的关联还不是特别大。

aaa 模块下的变动基本和 bbb 模块下的没啥关系,但是 aaa 变了,bbb 也要重新编译一遍,bbb 变了 aaa 也要重新编译一遍,这就很没必要。

有的同学说,那在 aaa 和 bbb 下分别放一个 tsconfig.json,各自编译各自的不就行了?

这样是可以,但是这样就是多次编译了,比较麻烦。

能不能还是一次编译,但是对一些相对独立的模块做下缓存,不要跟随别的模块一起编译呢?

可以的,这就是 Project Reference 做的事情了。

在 aaa 和 bbb 下各自创建一个 tsconfig.json,放各自的编译配置。注意这里要加一个 composite: true,这是 Project Reference 需要的:

4fe0fcb8dcc8044a31bafd74c061081a.png

然后在根目录的 tsconfig.json 里加上一个 references 的配置,引入 aaa 和 bbb:

4f47bc9378a1658137a4a6d7775f7d2c.png

这样再执行 tsc --build 进行编译,你会发现编译结果多了 .d.ts 的声明,还多了 tsconfig.tsbuildinfo 的文件:

1a221f72969e71c18fac08dcbd9ddfe1.png

打开 tsconfig.tsbuildinfo 看一下,会发现它记录了编译了哪些文件,还记录了这些文件的 hash 值:

4a0b09a8810e05f703d8a86208bb28bc.png

看到这里,你是不是就知道为啥它能实现缓存了?

没错,就是对比文件的 hash,当编译到这个 project 的时候,会对比下 hash 有没有变化,变了才去编译。没变的就直接跳过了。

而且,别的地方可能用到这个 project 的类型,所以需要生成 d.ts 声明文件,这就是为啥我们没有指定 declaration: true 的配置,但是编译产物里还是有 d.ts。其实这是 composite 选项做的,它设置了 Project Reference 需要的一些编译选项:

82fca5ac82ee8669df253e6efbf20363.png

现在当你修改了 aaa 下某个模块的代码,重新编译的时候就不会编译 bbb 了,只会编译 aaa 下的那个模块。

这就是 Project Reference 的作用。

当然,这种编译模式和常规的编译模式不同,所以不是直接用 tsc 来编译,而是用 tsc --build 或者 tsc -b。

此外,Project Reference 还支持通过 prepend 指定编译顺序,比如给 bbb 添加 prepend: true,那么就会先编译 bbb,再编译当前项目,然后编译 aaa:

c73a9b0f68dd4ae3a04a555194ac1b61.png

其实很容易想到,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 执行的速度比较慢的时候,不妨尝试一下。

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

4a61a4f8a86778227335fcd09c793e04.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值