Skip to content

Angular 9+ incorrectly flags template variables as not existing in pug templates #18290

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

Closed
1 task done
entith opened this issue Jul 17, 2020 · 6 comments · Fixed by #19114
Closed
1 task done

Angular 9+ incorrectly flags template variables as not existing in pug templates #18290

entith opened this issue Jul 17, 2020 · 6 comments · Fixed by #19114

Comments

@entith
Copy link

entith commented Jul 17, 2020

🐞 Bug report

Command (mark with an x)

  • serve

Is this a regression?

Yes, had no issues in Angular 8. I'm guessing this has something to do with Ivy.

Description

TS component:

import { Component } from '@angular/core';

@Component({
  selector: 'app-test',
  templateUrl: './test.component.pug',
  styleUrls: ['./test.component.sass']
})
export class TestComponent {

  items = [
    'one',
    'two',
    'three',
    'four'
  ];
}

Pug template:

ul
  li(*ngFor="let item of items") {{item}}

I have the above example component and template in an Angular project.

The project builds without issue using ng build and ng-build --prod

The dev server starts without any issues using ng serve and the page renders as expected.

Once I start making changes to the project and the dev server automatically rebuilds, it prints the following error:
Property 'item' does not exist on type 'TestComponent'. Did you mean 'items'?

The Angular application does appear to continue to work correctly and auto-rebuild on changes (printing that error every time),
but these false errors can potentially hide legitimate ones.

This happens with any variables generated with *ngIf or *ngFor.

  • div(*ngIf="name$ | async as name") {{name}}: the {{name}} portion will generate an error

This issue occurs in both Angular 9 and 10.

I have tried two different methods of adding pug support to my project, the error occurs with both:

🔬 Minimal Reproduction

Here is a repository resulting from the below steps: https://github.com/entith/ng-cli-pug-template-variable-issue

  1. run ng new test --minimal --skip-tests --style sass --routing
  2. switch to the generated project dir cd test
  3. run npm i -D @angular-builders/custom-webpack pug pug-loader apply-loader
  4. add custom-webpack.config.js file below
  5. edit angular.json as per the @angular-builders/custom-webpack documentation to use custom-webpack.config.js
  6. run ng g component test
  7. edit the component and its template file to match the example above
  8. run ng serve and wait for project to build
    • project should compile and server start with no errors
    • page should load in browser as expected
  9. make any non-breaking change to a project file and save to trigger a rebuild
    • ex: add a space at the end of a line in the test.component.pug file
    • the project should rebuild, print : Compiled successfully, and then a moment later the error should print
    • the page should have correctly refeshed
      • if you make any template changes or changed the items array in the component, the page should correctly reflect these changes

custom-webpack.config.js:

module.exports = (config, options, targetOptions) => {
  config.module.rules.push(
    {
      test: /\.pug$/,
      use: [
        { loader: "apply-loader" },
        { loader: "pug-loader" }
      ]
    }
  );
 
  return config;
};

🔥 Exception or Error


> ng serve

chunk {main} main.js, main.js.map (main) 20.6 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 141 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.15 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 12.7 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 3 MB [initial] [rendered]
Date: 2020-07-17T20:50:39.902Z - Hash: 6232187f38b85c2dde79 - Time: 5839ms
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
: Compiled successfully.

Date: 2020-07-17T20:50:44.744Z - Hash: d0680cf93388498b9aa8
4 unchanged chunks
chunk {main} main.js, main.js.map (main) 20.6 kB [initial] [rendered]
Time: 198ms
: Compiled successfully.
    
    ERROR in src/app/test/test.component.pug:4:36 - error TS2551: Property 'item' does not exist on type 'TestComponent'. Did you mean 'items'?
    
    4   li(*ngFor="let item of items") {{item}}
                                         ~~~~
    
      src/app/test/test.component.ts:5:16
        5   templateUrl: './test.component.pug',
                         ~~~~~~~~~~~~~~~~~~~~~~
        Error occurs in the template of component TestComponent.

🌍 Your Environment


Angular CLI: 9.1.11
Node: 12.18.2
OS: win32 x64

Angular: 9.1.12
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.901.11
@angular-devkit/build-angular     0.901.11
@angular-devkit/build-optimizer   0.901.11
@angular-devkit/build-webpack     0.901.11
@angular-devkit/core              9.1.11
@angular-devkit/schematics        9.1.11
@angular/cli                      9.1.11
@ngtools/webpack                  9.1.11
@schematics/angular               9.1.11
@schematics/update                0.901.11
rxjs                              6.5.5
typescript                        3.8.3
webpack                           4.42.0
@JoostK
Copy link
Member

JoostK commented Jul 18, 2020

AFAICS the error occurs because incremental rebuilds run the type checker in a separate process, in which the custom Webpack rules are not applied. So the template file that gets loaded is really just the raw pug template itself, such that the ngFor element is not expanded, leaving the {{item}} as the only Angular template syntax.

@angular-builders/custom-webpack is an external extension to the CLI and any customization achieved with it may cause incompatibility issues such as these.

@alan-agius4
Copy link
Collaborator

alan-agius4 commented Jul 18, 2020

As @JoostK mentioned in the fork type checker we only accept raw HTML and SVG templates.

What you can do to solve the issue is to disable fork type checking.

@ngbot ngbot bot added this to the needsTriage milestone Jul 18, 2020
@entith
Copy link
Author

entith commented Jul 18, 2020

Thanks for the replies, I know this isn't exactly a supported configuration so I appreciate it!

Disabling the fork type checker did indeed resolve the issue. For anyone reading this that doesn't know how, I added "forkTypeChecker": false to the build option in angular.json.

...
"architect": { 
  "build": { 
    "options": { 
      "forkTypeChecker": false,
      ...
    } 
  } 
} 
...

The downside now is that with my tiny one component demo application, the incremental rebuild jumped from around 225ms to 1250ms.

Is there any reasonable way to add custom rules to the Webpack config the forked type checker uses?

@clydin
Copy link
Member

clydin commented Jul 20, 2020

The forked type checker does not use Webpack so unfortunately there is no Webpack config to augment.
However, the new Angular Webpack compiler plugin (PR) currently in development does not use the forked type checker. The new plugin will as a result resolve this issue without the build performance degradation. Please note though that the earliest the new plugin will be included for default use would be v11.

@entith
Copy link
Author

entith commented Jul 20, 2020

Great! Glad to hear us difficult folk's nonsense will continue to work.

I will probably stick with Angular 8 for now and keep an eye on that PR/v11.

Thanks for the help and explanations!

@entith entith closed this as completed Jul 20, 2020
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Aug 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants