-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Add assumeChangesOnlyAffectDirectDependencies as a option to skip checking and generating .d.ts files for files indirectly importing affected file #35711
Conversation
…ts files for files indirectly importing affected file Fixes #33329
@sheetalkamat Very nice. Just tested this using the test case from #33329 and confirmed that recompile time is now very similar to gulp-tsb /cc @jrieken |
@RyanCavanaugh @DanielRosenwasser Do you think the name of the flag is ok or otherwise please suggest something. Note that its not just check that gets disabled but also ".d.ts" emit of these indirectly importing files. |
? |
|
You left a laugh reaction, but I'm like half serious |
That’s perfect; I’m only half laughing 👍 |
|
|
@@ -433,7 +433,9 @@ namespace ts { | |||
return; | |||
} | |||
|
|||
forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, (state, path) => handleDtsMayChangeOf(state, path, cancellationToken, computeHash)); | |||
if (!state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To someone unfamiliar with the builder, it's not clear how adding this simple check does what it says in the description. Where are the direct dependencies handled if not in the call below? At what point is the list expanded to include indirect dependencies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getAffectedFiles handle the direct dependency and the below function handles indirect ones.
affectsSemanticDiagnostics: true, | ||
affectsEmit: true, | ||
category: Diagnostics.Advanced_Options, | ||
description: Diagnostics.Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this is probably a very ignorant question, but does this apply only within projects or across projects as well? Clearly we can't get everything into the name, but it might be nice to provide more details in the description (or in a a comment, if we'd prefer to keep the switch mysterious and little-used).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Builder is not used across projects but within single program.
@sheetalkamat this PR added at least one test that causes long-path problems on git for windows. Could you try to shorten it?
There is a flag for git that might resolve the issue, but it seems better to just rename the test. |
I'm probably misunderstanding the point of assumeChangesOnlyAffectDirectDependencies, but I'm testing it on a large project on 3.8RC, and it doesn't seem to have any effect. For historical reasons, our project does not use modules, just namespaces at the file level. With the assumeChangesOnlyAffectDirectDependencies option on (and incremental), I make a test change in a file that is referenced (as far as I can tell) in a three other files. However, I see most files in the project are built, and it's still taking me 20 seconds to build our project when a small change is made. Thanks for all your hard work on this great project. Happy to provide any other diagnostics / output that would be of help. |
Unfortunately that's as expected - codebases with global files don't have an explicit dependency graph, and every file is considered a direct dependency of a global. |
@DanielRosenwasser we’re having the same issue as @mathias999us, but I don’t understand your comment. Can you clarify what’s the difference between codebases with and without global files? Previously we specified an array of files in the What could we be doing wrong? Many thanks (and apologies if this is not the right place to ask)! |
If your files are all global, TypeScript assumes that they are all compose into one big ball of globals that can impact each other in arbitrary ways. Regardless of any sort of arrangement based on file order or For example, imagine 3 files // a.ts
var x: string; // b.ts
var x: string; // c.ts
var c: string; Now imagine another global file comes along // d.ts
var x: number; That declaration of Or, as a more 3D diagram might illustrate My recommendation is to move off of global code (which our team is in the process of at #35561) |
@DanielRosenwasser Thanks for that straight-forward (and comical) explanation. However, our situation is still slightly different than the example you gave. We house all our code in namespaces at the file level (old-style TypeScript modules). I would think the TypeScript compiler should be able to determine that it only needs to compile other files that reference the namespace whose content is being changed. |
Namespaces are really just declarations that sit in the global scope - in theory we could do more work to say that when all files contain exactly one namespace, we can synthesize the dependency graph after type-checking and try to reuse it between compiles - but that's actually very different from the logic we use to establish dependencies between files today and would be a lot of work. My gut says that a better way forward is to migrate to modules since that's where the majority of our investment as well as the community has been going. Additionally, we've been building some tooling for ourselves to do that which you can leverage. |
Great addition, thank you for the awesome work! Is it safe to always set |
@kripod they're not necessarily related - you can have top-level statements that cause side-effects, but don't add or remove any global declarations. This feature is really about enabling faster iteration time by only recompiling the files that directly import a file. It relies on an assumption that given |
Fixes #33329 by providing this flag to allow
gulp-tsb
like buildcc: @mjbvz