Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix emit signature to enable incremental work to function properly #150

Merged
merged 9 commits into from Mar 13, 2024

Conversation

skywalker512
Copy link
Contributor

@skywalker512 skywalker512 commented Mar 13, 2024

vue-tsc has undergone significant changes compared to previous versions, and it seems to work similarly to tsc. (Thank you for your hard work ❤️)

I found that after modifying a vue file and enabling incremental compilation at a project scale similar to tsc, vue-tsc is much slower than tsc (using generateTrace with vue-tsc reveals a large number of file checks).

Below is my debugging process, which may not be entirely correct (as I am not familiar with TypeScript), but should indicate the issue.

For example, in the following file relationship scenario where A imports B and B modifies internally code while A does not:

I found that getBinderAndCheckerDiagnosticsOfFile reads cachedDiagnostics from semanticDiagnosticsPerFile, and if retrieved, it will not check again.

However, neither A nor B are in semanticDiagnosticsPerFile (ideally A should not need checking; it should be in this list).

I discovered that when handling B at handleDtsMayChangeOfReferencingExportOfAffectedFile, A was removed.

Testing React & tsc projects revealed that if only internal code of "B" is modified, "B"'s signature remains unchanged.

However, within vue-tsc's fileInfos, signatures always equal to version (I currently unclear about the relationship between version signatures and content; version appears related to file content?).

Ultimately I found during computeDtsSignature, emit includes a forceDtsEmit parameter; however, this parameter is not passed by vue-tsc's decorateProgram.

This results in TypeScript always using version as the signature.

Sorry, my English is not good, I will still use Chinese to describe it.


vue-tsc 相较于之前版本有比较大的变化,似乎和 tsc 工作模式差不多。(感谢你们辛苦的工作)

我发现在修改了 vue 文件之后,在同时开启 incremental,差不多的项目规模的情况下 vue-tsc 相较于 tsc 会慢很多(使用 generateTrace vue-tsc 发现会有大量文件的 check)

下面是我的 debug 过程,可能不一定正确(我不熟悉 typescript),但是应该指示了这个问题。

例如有下面的文件关系,A import B, B 修改了自身内部的东西,A 没有修改。

我发现 getBinderAndCheckerDiagnosticsOfFile 会从 semanticDiagnosticsPerFile 中读取 cachedDiagnostics,如果获取到将不会再次 check

但是 A 和 B 都没有在 semanticDiagnosticsPerFile 中(理想情况下 A 应该不需要进行 check, A 应该在该列表中)

我发现 A 是处理 B 时在 handleDtsMayChangeOfReferencingExportOfAffectedFile删除的。

我测试了 React & tsc 项目发现,如果只修改了 “B” 内部代码,不会修改 “B” 的 signature

但是 vue-tsc 中的 fileInfos 里面的 signature 似乎总是 version (我现在还对 version signature 的关系不怎么明确,version 似乎总是和文件内容有关),所以这里会导致 A 从 semanticDiagnosticsPerFile 删除(因为 A import B)

最终我发现在 computeDtsSignature 的时候,emit 有 forceDtsEmit 这个参数,而 vue-tsc 在 decorateProgram 时没有传递这个参数

导致 typescript 总是使用 version 作为 signature

@johnsoncodehk johnsoncodehk merged commit 3af2f71 into volarjs:master Mar 13, 2024
3 checks passed
@johnsoncodehk
Copy link
Member

Thank you very much for the survey! Can you share how much time this change has reduced on your project?

@skywalker512
Copy link
Contributor Author

I have a Real project with ~1600 files, it takes about 10s (AMD 7K62) and 4s (M3 Pro) in the case of incremental work. The full time needed is 25s (AMD 7K62) and 8s (M3 Pro).

However, I found that in a pure TS project of the same scale, incremental will have a significant advantage, only taking 2~3s(vue-tsc use 10s) to complete on AMD 7K62.

I found that vue takes a lot of time in createSourceFile using generateTrace.

About 100 lines of files, ts only needs ~300 us, vue needs 5ms.


I also have a question, is incremental safe? I see that some virtual files are generated, but there is no record in tsbuildInfo.

@johnsoncodehk
Copy link
Member

It is safe when you do not change vueCompilerOptions. Some options in vueCompilerOptions will affect virtual code generation. When it changes, you need to delete .tsbuildinfo and perform a complete build again. I'm currently not sure if it's possible to document vueCompilerOptions in .tsbuildinfo to support increments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants