打字稿编译速度 - 尝试解决方法但坚持合并

tts*_*ras 8 typescript

我在过去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=...
Run Code Online (Sandbox Code Playgroud)

...在每个.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
Run Code Online (Sandbox Code Playgroud)

...它做了两件事:它使用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
Run Code Online (Sandbox Code Playgroud)

我将把这个问题留待未来的贡献......

Gip*_*ing 0

我也从 Makefile 开始tsc --out,但我现在使用requirejstsc --watch --module amd

可能有更好的替代方案tsc --watch(它不是很快),但是 requirejs 具有您可以使用的好处(import除了// <reference.../>.d.ts 文件),并且 requirejs 还可以稍后捆绑和优化您的项目。