在过去的 3 个月里,我一直在使用 Typescript 创建非常复杂的 CRUD 应用程序。Typescript 提供的编译时安全性为我的工作提供了显着的加速 - 在编译时捕获错误是天赐之物,而不是在运行时将它们表现为异常和不当行为。
不过,有一个问题。
我必须处理数百个表,所以我使用的是从 DB 模式开始的定制代码生成器,并自动生成大量 Typescript 文件。只要架构很小,它就可以完美地工作 - 但是对于包含数百个表的非常大的架构,tsc 的编译时间正在成为一个问题 -我看到一组 400 个文件的编译时间为 15 分钟...... (以及“CALL_AND_RETRY_2 分配失败”的可怕编译错误 - 即内存不足问题......)
到目前为止,我一直在 Makefile 中使用 tsc,使用“tsc --out ...”语法调用它,从我的所有 .ts 文件生成单个 .js。因此,我认为我可以通过以增量方式进行构建来解决这个问题:单独编译每个 .ts(即一次只将一个 .ts 文件传递给 tsc),最后连接所有生成的.js 在一个单一的。这似乎确实有效 - 在正常开发期间只需要重新编译更改的文件(并且只有初始编译通过所有这些文件,因此需要很多时间)。
但事实证明,这也有一个问题:为了让每个 .ts “独立编译”,我必须在顶部添加所有相关的依赖项——也就是说,像这样的行
/// <reference path=...
...在每个 .ts 文件的顶部。
事实证明,由于这些引用,生成的 .js 文件包含相同的部分,这些部分在许多部分中重复......所以当我连接 .js 文件时,我得到相同函数的多个定义,更糟糕的是,全局范围语句(var global = new ...)重复!
因此,我需要一种以某种方式智能地“合并”生成的 .js 文件的方法,以避免看到重复的函数定义......
有没有办法以一种巧妙的方式进行合并,避免重复?或者也许是其他加速编译的方法?
欢迎提出任何建议... tsc 编译速度比普通编译器慢 30-100 倍 - 现在它确实是一个阻塞点。
更新,2天后
Basarat(见下面他的回答)帮助我将他的解决方案应用到我的项目中。事实证明,即使他的解决方案适用于小型和中等规模的项目,但我得到了可怕的“致命错误:CALL_AND_RETRY_2 分配失败 - 进程内存不足”错误 - 这与我使用“tsc”时遇到的错误相同 - 出去 ...”。
最后,我的基于 Makefile 的解决方案是唯一有效的方法 - 这样做:
%.js: %.ts
@UPTODATE=0 ; \
if [ -f "$<".md5 ] ; then \
md5sum -c "$<".md5 >/dev/null 2>&1 && { \
UPTODATE=1 ; \
} ; \
fi ; \
if [ $$UPTODATE -eq 0 ] ; then \
echo Compiling $< ; \
tsc --sourcemap --sourceRoot /RevExp/src/ --target ES5 $< || { \
rm $@ "$<".md5 ; \
exit 1 ; \
} ; \
md5sum "$<" > "$<".md5 ; \
fi
...它做了两件事:它使用 MD5 校验和来确定何时实际执行编译,并以“独立”方式进行编译(即没有 tsc 的“--out”选项)。
在实际的目标规则中,我曾经合并生成的 .js 文件......但这让我没有工作 .map 文件(用于调试) - 所以我现在在 index.html 中生成了直接包含:
${WEBFOLDER}/index.html: $(patsubst %.ts,%.js,${CONTROLLERS_SOURCES}) ${WEBFOLDER}/index.html.template
cat ${WEBFOLDER}/index.html.template > $@ || exit 1
REV=$$(cat revision) ; \
for i in $(patsubst %.ts,%.js,${CONTROLLERS_SOURCES}) ; do \
BASE=$$(basename $$i) ; \
echo " <script type='text/javascript' src='js/$${BASE}?rev=$$REV'></script>" >> $@ ; \
done || exit 1
cat RevExp/templates/index.html.parallel.footer >> $@ || exit 1
cp $(patsubst %.ts,%.js,${CONTROLLERS_SOURCES}) ${WEBFOLDER}/js/ || exit 1
我将把这个问题留给未来的贡献......