当前位置: 首页 > 科技观察

TypeScript编译性能优化:ProjectReference_0

时间:2023-03-15 18:37:10 科技观察

TypeScript为JavaScript增加了一个类型系统,可以在编译时检查类型错误,增加了代码的健壮性,但也增加了一个编译过程。ts编译的速度和项目的大小有关。如果项目比较大,代码比较多,编译时间会比较长。有什么办法可以提高tsc编译的性能吗?事实上,TypeScript3.0实现了项目引用功能,用于优化编译和类型检查的性能。什么是项目参考?ProjectReference想象了这样一个场景。项目目录下有两个相对独立的模块aaa和bbb。它们使用相同的tsconfig.json来配置编译方式:执行tsc会将所有的include文件编译到dist目录下:假设aaa和bbb都比较大,那么编译时间会比较长,但是两者的关系是不是特别大。aaa模块下的变化基本上和bbb模块没有关系,但是aaa变化了,bbb需要重新编译,bbb变化了,aaa需要重新编译,这是不必要的。有同学说,为什么不在aaa和bbb下分别放一个tsconfig.json,自己编译呢?这个是可以的,但是这样编译多次,比较麻烦。是否还能编译一次,只是缓存一些相对独立的模块,而不是和其他模块一起编译?是的,这就是ProjectReference所做的。分别在aaa和bbb下创建一个tsconfig.json,放上各自的编译配置。注意这里加了一个composite:true,这是ProjectReference需要的:然后在根目录的tsconfig.json中添加一个references的配置,并导入aaa和bbb:然后执行tsc--build编译,就可以了发现编译结果多了.d.ts的声明,多了tsconfig.tsbuildinfo文件:打开tsconfig.tsbuildinfo看一下,会发现它记录了哪些文件已经编译了,还记录了这些文件的哈希值:看到这里,你知道为什么它可以实现缓存吗?没错,就是比较文件的hash。编译这个项目的时候,会比较hash是否有变化,然后编译。只是跳过它而不改变它。而且这类工程在其他地方可能会用到,所以需要生成一个d.ts声明文件,这也是为什么我们没有指定declaration:true配置,但是编译出来的产品里面还是有d.ts的。其实这是通过composite选项完成的,它设置了ProjectReference需要的一些编译选项:现在修改aaa下某个模块的代码,重新编译时bbb不会编译,只有aaa下的会编译编译模块。这就是项目参考的用途。当然,这种编译方式不同于常规的编译方式,所以不是直接用tsc编译,而是用tsc--build或tsc-b。另外,ProjectReference还支持通过prepend指定编译顺序,比如给bbb加上prepend:true,那么bbb会先编译,然后是当前项目,最后是aaa:其实很容易想到ProjectReference可用于提高monorepotsc编译性能。因为monorepo下的多个项目是相对独立的,一个模块的改动一般不会影响到另一个,所以在编译时应该单独缓存。总结TypeScript3.0实现项目参考以优化性能。如果项目下有一些相对独立的模块,其他模块的改动不会影响,但需要重新编译,这时可以使用ProjectReference进行优化。在独立模块下添加tsconfig.json,添加复合编译选项,在入口tsconfig.json中配置引用,引用这些独立模块。然后执行tsc--build或tsc-b编译。这时候就实现了编译和类型检查的性能优化。原理是编译时会生成tsconfig.tsbuildinfo文件,里面记录了编译后的文件和它们的hash。再次编译时,如果文件hash没有变化,则直接跳过,从而提高编译速度。这是TypeScript提供的编译性能优化机制。当项目比较大,tsc的执行速度比较慢的时候,不妨试试看。