gulp-typescript 增量编译是如何工作的?
How does gulp-typescript incremental compilation work?
gulp-typescript 的自述文件说 supports incremental compilation 但没有解释该术语在此上下文中的含义。
有一篇 issue 讨论了 gulp-typescript 增量编译如何比 tsc 慢,但它没有解释原因或区别。
gulp-typescript 在 "incremental compilation" 时在做什么?
我试过的
我正在查看 gulp-typescript 的源代码,看起来 gulp-typescript 根本没有进行任何增量编译。
创建 Project
时,它会关闭 ProjectInfo
的实例,该实例具有 input
成员,即 FileCache
。 FileCache 几乎是从文件名到源字符串的映射。在 gulp-打字稿 Project
.
中没有维护太多其他状态
为了使用 TS 编译器 API 进行实际的增量编译(在后续构建中重用编译过程的产物),我希望看到以下内容之一:
但我在源代码中没有看到任何一个。
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
更快
Gulp-typescript 有两种不同的方式来编译你的文件。默认方法编译整个项目并进行类型检查。这是在 lib/compiler.ts
中的 ProjectCompiler
中实现的。另一个单独编译每个文件,并在您设置 isolatedModules: true
时激活。该方法在 lib/compiler.ts
中的 FileCompiler
中实现。
FileCompiler只需要编译发生变化的文件即可。未更改的文件被缓存,就像 Achmedzhanov 在他的回答中描述的那样。
然而,大多数用户使用 ProjectCompiler,因为类型检查可能是他们使用 TypeScript 的原因。我认为您的问题与此 ProjectCompiler 有关。增量编译通过调用 TypeScript API 导出的 ts.createProgram
来处理。通过传递旧程序,TypeScript API 将重用以前编译的一些信息。您可以在这里找到源代码:
过去这足以获得增量编译,但在较新版本的 TypeScript 中已经发生了变化。我们将需要切换到新的 API,可能会使用您提到的 API 之一,但我不熟悉这些。
在您的问题中,您提到了 FileCache。这用于存储在输入流中传递的所有文件。 gulp API 即在流中给出所有文件,而 TypeScript API 是同步的。因此,我们需要等到我们拥有所有输入文件。此外,我们使用FileCompiler中的FileCache来检测文件是否发生变化,从而判断是否需要重新编译。
gulp-typescript 的自述文件说 supports incremental compilation 但没有解释该术语在此上下文中的含义。
有一篇 issue 讨论了 gulp-typescript 增量编译如何比 tsc 慢,但它没有解释原因或区别。
gulp-typescript 在 "incremental compilation" 时在做什么?
我试过的
我正在查看 gulp-typescript 的源代码,看起来 gulp-typescript 根本没有进行任何增量编译。
创建 Project
时,它会关闭 ProjectInfo
的实例,该实例具有 input
成员,即 FileCache
。 FileCache 几乎是从文件名到源字符串的映射。在 gulp-打字稿 Project
.
为了使用 TS 编译器 API 进行实际的增量编译(在后续构建中重用编译过程的产物),我希望看到以下内容之一:
但我在源代码中没有看到任何一个。
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
更快Gulp-typescript 有两种不同的方式来编译你的文件。默认方法编译整个项目并进行类型检查。这是在 lib/compiler.ts
中的 ProjectCompiler
中实现的。另一个单独编译每个文件,并在您设置 isolatedModules: true
时激活。该方法在 lib/compiler.ts
中的 FileCompiler
中实现。
FileCompiler只需要编译发生变化的文件即可。未更改的文件被缓存,就像 Achmedzhanov 在他的回答中描述的那样。
然而,大多数用户使用 ProjectCompiler,因为类型检查可能是他们使用 TypeScript 的原因。我认为您的问题与此 ProjectCompiler 有关。增量编译通过调用 TypeScript API 导出的 ts.createProgram
来处理。通过传递旧程序,TypeScript API 将重用以前编译的一些信息。您可以在这里找到源代码:
过去这足以获得增量编译,但在较新版本的 TypeScript 中已经发生了变化。我们将需要切换到新的 API,可能会使用您提到的 API 之一,但我不熟悉这些。
在您的问题中,您提到了 FileCache。这用于存储在输入流中传递的所有文件。 gulp API 即在流中给出所有文件,而 TypeScript API 是同步的。因此,我们需要等到我们拥有所有输入文件。此外,我们使用FileCompiler中的FileCache来检测文件是否发生变化,从而判断是否需要重新编译。