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

The component cache is not reset until you change the component #18707

Open
KostyaTretyak opened this issue Sep 5, 2020 · 3 comments
Open

The component cache is not reset until you change the component #18707

KostyaTretyak opened this issue Sep 5, 2020 · 3 comments

Comments

@KostyaTretyak
Copy link

@KostyaTretyak KostyaTretyak commented Sep 5, 2020

🐞 Bug report

Command

  • serve

Is this a regression?

Yes, I think it's a regression.

Description

If you first create a component without importing the necessary modules, and then add these necessary modules, the component is not updated until you change the component itself.

Not sure if this bug is Angular CLI, maybe it's more of an Angular Material bug.

🔬 Minimal Reproduction

Step 1

ng new my-project
cd my-project
ng add @angular/material

Step 2
In src/app/app.module.ts import only ReactiveFormsModule and MatFormFieldModule:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    ReactiveFormsModule,
    MatFormFieldModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Step 3
Put this code to src/app/app.component.html:

<mat-form-field>
  <input matInput>
</mat-form-field>

Step 4

ng serve

In console the browser see:

ERROR Error: mat-form-field must contain a MatFormFieldControl.

Step 5
Import MatInputModule:

import { MatInputModule } from '@angular/material/input';
// ...
imports: [
//..
  MatInputModule
]

In the browser still:

ERROR Error: mat-form-field must contain a MatFormFieldControl.

Step 6

Make any change in src/app/app.component.ts and the error disappear.

🌍 Your Environment


Angular CLI: 10.0.8
Node: 12.18.3
OS: linux x64

Angular: 10.0.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, platform-server, router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.1000.8
@angular-devkit/build-angular     0.1000.8
@angular-devkit/build-optimizer   0.1000.8
@angular-devkit/build-webpack     0.1000.8
@angular-devkit/core              10.0.8
@angular-devkit/schematics        10.0.8
@angular/cdk                      10.1.3
@angular/cli                      10.0.8
@angular/material                 10.1.3
@ngtools/webpack                  10.0.8
@nguniversal/builders             10.0.2
@nguniversal/common               10.0.0
@nguniversal/express-engine       10.0.0
@schematics/angular               10.0.8
@schematics/update                0.1000.8
rxjs                              6.5.5
typescript                        3.9.7
webpack                           4.43.0
@JoostK
Copy link
Member

@JoostK JoostK commented Sep 6, 2020

I can reproduce, but only with the CLI. ngtsc's emit does emit both app.module.ts and app.component.ts, but the update to app.component.ts does not end up in the Webpack bundle.

@KostyaTretyak KostyaTretyak changed the title The component cache is not reset until you change it The component cache is not reset until you change the component Sep 6, 2020
@ngbot ngbot bot modified the milestone: needsTriage Sep 7, 2020
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Sep 7, 2020
@alan-agius4
Copy link
Collaborator

@alan-agius4 alan-agius4 commented Sep 7, 2020

I had a look and it and the problem is that the NGTSC compiler adds a reversed dependency app.component.ts -> app.module.ts. Webpack, however is not aware of this dependency and therefore when app.module.ts is changed it will not request app.component.ts.

class AppComponent {
    constructor() {
        this.title = 'material-test';
    }
}
AppComponent.ɵfac = function AppComponent_Factory(t) { return new (t || AppComponent)(); };
AppComponent.ɵcmp = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({ type: AppComponent, selectors: [["app-root"]], decls: 2, vars: 0, consts: [["matInput", ""]], template: function AppComponent_Template(rf, ctx) { if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "mat-form-field");
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](1, "input", 0);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    } }, directives: [_angular_material_form_field__WEBPACK_IMPORTED_MODULE_1__["MatFormField"], _angular_material_input__WEBPACK_IMPORTED_MODULE_2__["MatInput"]], styles: ["\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJzcmMvYXBwL2FwcC5jb21wb25lbnQuY3NzIn0= */"] });
/*@__PURE__*/ (function () { _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AppComponent, [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"],
        args: [{
                selector: 'app-root',
                templateUrl: './app.component.html',
                styleUrls: ['./app.component.css']
            }]
    }], null, null); })();

In @ngtools/webpack, we retrieve dependencies by analysing a source file and extract import and export declarations. Since app.component.ts doesn't import app.module.ts, we don't mark the former as dependant on the latter.

It seems to me that the NGTSC compiler should offer an API to retrieve such dependencies.

@alan-agius4
Copy link
Collaborator

@alan-agius4 alan-agius4 commented Sep 7, 2020

@clydin talked to @alxhub in the past to introduce something like getModuleDependencies which would go along getResourceDependencies proposed here angular/angular#38048.

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

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.