Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upivy loses query results in abstract @Directive() when CLI rebuilt (file change) #32416
Comments
This comment has been minimized.
This comment has been minimized.
I think this is a problem with ngtsc incremental compilation? |
This comment has been minimized.
This comment has been minimized.
I think the solution would be for ngtsc to include all ancestors of components as dependencies that would trigger a rebuild of that component. |
This comment has been minimized.
This comment has been minimized.
This shouldn't need to be the case (for locality) but probably should be because of type-checking. |
This comment has been minimized.
This comment has been minimized.
Will this be solved for 9.0 final? |
This comment has been minimized.
This comment has been minimized.
I think it should. We just need someone with time to look into it. :-/ |
This comment has been minimized.
This comment has been minimized.
This also happens when no Directives are involved (only components). I have a setup of AppComponent and LayoutComponent and only included the LayoutComponent within the AppComponent markup and the project runs fine immediately after Thankfully setting |
This comment has been minimized.
This comment has been minimized.
Here's a breakdown of the issue: Abstract directives are not registered with an NgModule, so if the directive is updated the NgModule is not invalidated. The component subclass however is correctly tracked as being dependent on its parent. During incremental state reconciliation, this means that the change to the abstract directive has this effect:
During the subsequent compilation, the NgModule is considered to be safe to skip, which means that none of its metadata is analyzed and registered with angular/packages/compiler-cli/src/ngtsc/scope/src/local.ts Lines 113 to 119 in a42057d Notice how this is responsible for the knowledge of which declarations correspond with which NgModule. The abstract directive and component are reanalyzed, because their source file is correctly deemed unsafe to skip analyzing. Consequently, the component requests its module scope:
angular/packages/compiler-cli/src/ngtsc/scope/src/local.ts Lines 129 to 131 in a42057d is no longer available, as the component resides in a file for which no metadata was copied over during incremental state reconciliation as its metadata was deemed outdated (because of the dependency on the abstract directive). |
During incremental compilations, ngtsc needs to know which metadata from a previous compilation can be reused, versus which metadata has to be recomputed as some dependency was updated. Changes to directives/components should cause the NgModule in which they are declared to be recompiled, as the NgModule's compilation is dependent on its directives/components. When a dependent source file of a directive/component is updated, however, a more subtle dependency should also cause to NgModule's source file to be invalidated. During the reconciliation of state from a previous compilation into the new program, the component's source file is invalidated because one of its dependency has changed, ergo the NgModule needs to be invalidated as well. Up until now, this implicit dependency was not imposed on the NgModule. Additionally, any change to a dependent file may influence the module scope to change, so all components within the module must be invalidated as well. Fixes angular#32416
During incremental compilations, ngtsc needs to know which metadata from a previous compilation can be reused, versus which metadata has to be recomputed as some dependency was updated. Changes to directives/components should cause the NgModule in which they are declared to be recompiled, as the NgModule's compilation is dependent on its directives/components. When a dependent source file of a directive/component is updated, however, a more subtle dependency should also cause to NgModule's source file to be invalidated. During the reconciliation of state from a previous compilation into the new program, the component's source file is invalidated because one of its dependency has changed, ergo the NgModule needs to be invalidated as well. Up until now, this implicit dependency was not imposed on the NgModule. Additionally, any change to a dependent file may influence the module scope to change, so all components within the module must be invalidated as well. This commit fixes the bug by introducing additional file dependencies, as to ensure a proper rebuild of the module scope and its components. Fixes angular#32416
During incremental compilations, ngtsc needs to know which metadata from a previous compilation can be reused, versus which metadata has to be recomputed as some dependency was updated. Changes to directives/components should cause the NgModule in which they are declared to be recompiled, as the NgModule's compilation is dependent on its directives/components. When a dependent source file of a directive/component is updated, however, a more subtle dependency should also cause to NgModule's source file to be invalidated. During the reconciliation of state from a previous compilation into the new program, the component's source file is invalidated because one of its dependency has changed, ergo the NgModule needs to be invalidated as well. Up until now, this implicit dependency was not imposed on the NgModule. Additionally, any change to a dependent file may influence the module scope to change, so all components within the module must be invalidated as well. This commit fixes the bug by introducing additional file dependencies, as to ensure a proper rebuild of the module scope and its components. Fixes #32416 PR Close #33522
This comment has been minimized.
This comment has been minimized.
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Command
Description
In IVY v9 (see here), we'll need to add abstract
@Directive()
on abstracts classes we extends that contain Angular stuff (like Input, ViewChild, DI).After add
@Directive()
on my abstract class and runng serve
everything works well.But If I edit abstract directive file and save, browser autoreload but query results are not resolved anymore ?!?!
One line repro :
git clone https://github.com/elvisbegovic/issue-ivy-abstract-directive.git && cd issue-ivy-abstract-directive && npm i && ng s
Open browser localhost:4200, open devtools console, you will see consoel without error, viewchild is available.
Edit or comment anything in any-abstract-class.ts file (cli rebuild + autoreload browser) you can see error at runtime that viewchild
this.myList
is undefined.GIF:

After browser auto reload :
In CLI console :
ERROR in src/app/app.component.ts(8,5): error TS8001: 'my-list' is not a valid HTML element.
See environment
Anything else relevant?
Problem is only when you edit
any-abstract-class.ts
file, if after first build you edit other file = no error.If I add
selector
to Directive and add it to NgModuledeclarations[]
, all works as before.This is working in View Engine (jit and aot and without decorating abstract classes)
Maybe related to #31560 and all referenced issues
Maybe this can live on angular/angular ?