gulp-typescript增量编译如何工作?

时间:2019-02-15 20:25:30

标签: typescript incremental-build gulp-typescript

gulp-typescript的自述文件说supports incremental compilation,但在这种情况下没有解释该术语的含义。

issue讨论了gulp-typescript增量编译比tsc慢,但没有解释原因或区别。

gulp-typescript在执行“增量编译”时是做什么的?

我尝试过的

我正在看gulp-typescript的源代码,看来gulp-typescript根本没有进行任何增量编译。 创建Project时,它将关闭ProjectInfo的实例,该实例具有一个input成员,该成员是FileCache。 FileCache几乎是从文件名到源字符串的映射。 gulp类型的脚本Project中并没有维护其他状态。

为了使用TS编译器API进行实际的增量编译(在后续版本中重用编译过程的产品),我希望看到以下内容之一:

但是我在源中看不到任何一个。

2 个答案:

答案 0 :(得分:4)

Gulp-typescript有两种不同的方式来编译文件。默认方法将编译整个项目并进行类型检查。这是在ProjectCompiler的{​​{1}}中实现的。另一个则分别编译每个文件,并在设置lib/compiler.ts时激活。该方法在isolatedModules: true的{​​{1}}中实现。

FileCompiler仅需要编译已更改的文件。像Achmedzhanov在其答案中描述的那样,未更改的文件将被缓存。

但是,大多数用户都使用ProjectCompiler,因为类型检查可能是他们使用TypeScript的原因。我认为您的问题与该ProjectCompiler有关。增量编译由TypeScript API导出的对FileCompiler的调用来处理。通过传递旧程序,TypeScript API将重用以前编译的某些信息。您可以在此处找到源代码:

https://github.com/ivogabe/gulp-typescript/blob/ea22fb7fe4295979e32a9d07b007e3f7473be8b5/lib/compiler.ts#L80

过去足以进行增量编译,但是在TypeScript的较新版本中已更改。我们可能需要使用您提到的一种API来切换到新的API,但我对这些API并不熟悉。

在您的问题中,您提到了FileCache。这用于存储在输入流中传递的所有文件。 gulp API即提供流中的所有文件,而TypeScript API是同步的。因此,我们需要等到拥有所有输入文件。此外,我们使用FileCompiler中的FileCache来检测文件是否已更改,因此是否需要重新编译。

答案 1 :(得分:1)

gulp-typescript缓存已编译的js文件,当某些文件被更改时,它将编译一个 https://github.com/ivogabe/gulp-typescript/blob/master/lib/compiler.ts#L282

if (this.project.input.getFileChange(file.fileNameOriginal).state === FileChangeState.Equal) {
    // Not changed, re-use old file.

    const old = this.previousOutput[file.fileNameNormalized];
    this.write(file, old.fileName, old.diagnostics, old.content, old.sourceMap);

    return;
}

const output: ts.TranspileOutput = this.project.typescript.transpileModule(file.content, {
    compilerOptions: this.project.options,
    fileName: file.fileNameOriginal,
    reportDiagnostics: true,
    transformers: this.finalTransformers ? this.finalTransformers() : undefined,
});

即使是一次文件编译也会导致导入依赖项的分析,因此不会比tsc --watch更快