Ivy : can’t use custom loader for component’s ‘templateUrl’

🐞 bug report

Affected Package

The issue is caused by package @angular/compiler-cli

Is this a regression?

Yes, it works without ivy

Description

If I apply a custom loader for templateUrls I have validation errors from Ivy.
It seems like it doesn’t use webpack file rules for templateUrl.

If I use JIT mode:

  • build error

In AOT mode:

  • builds fine
  • works fine
  • with ng serve everything seems fine but there is the error in the terminal’s output
config.module.rules.unshift(
    {
      test: /.(pug|jade)$/,
      exclude: /.(include|partial).(pug|jade)$/,
      use: [{loader: 'apply-loader'}, {loader: 'pug-loader'}]
    },
    {test: /.(include|partial).(pug|jade)$/, loader: 'pug-loader'},
    {test: /\.html$/, loader: 'raw-loader'}
  );

🔬 Minimal Reproduction

https://github.com/MateEke/angular-reproduction

ng build – fails
ng serve – fails
ng build --prod – works fine
ng serve --aot – everything seems fine except there is an error in the command output

🔥 Exception or Error


ERROR in Errors parsing template: Unexpected character "EOF" (Do you have an unescaped "{" in your template? Use "{{ '{' }}") to escape it.) ("
      a([routerLink]="['/']", [state]="{test: 'szia'}") Test link

router-outlet
[ERROR ->]"): C:/xampp/htdocs/angular-reproduction/src/app/app.component.pug@11:0, Invalid ICU message. Missing '}'. ("
      a([routerLink]="['/']", [state]="{test: 'szia'}") Test link

router-outlet
[ERROR ->]"): C:/xampp/htdocs/angular-reproduction/src/app/app.component.pug@11:0

🌍 Your Environment

Angular Version:


Angular CLI: 8.0.0
Node: 12.3.1
OS: win32 x64
Angular: 8.0.0
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router, service-worker

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.800.0
@angular-devkit/build-angular     0.800.0
@angular-devkit/build-optimizer   0.800.0
@angular-devkit/build-webpack     0.800.0
@angular-devkit/core              8.0.0
@angular-devkit/schematics        8.0.0
@angular/pwa                      0.800.0
@ngtools/webpack                  8.0.0
@schematics/angular               8.0.0
@schematics/update                0.800.0
rxjs                              6.5.2
typescript                        3.4.5
webpack                           4.30.0

Anything else relevant?
possible related: #14534

2 thoughts on “Ivy : can’t use custom loader for component’s ‘templateUrl’

  1. We experience the same. The “dirty” workaround I’ve found is to apply the following change:

    --- node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js
    +++ node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js
    @@ -304,6 +304,14 @@
                 strictExportPresence: true,
                 rules: [
                     {
    +                    test: /\.html$/,
    +                    loader: 'raw-loader',
    +                },
    +                {
    +                    test: /\.pug$/,
    +                    loaders: ['apply-loader', 'pug-loader']
    +                },
    +                {
                         test: /\.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
                         loader: 'file-loader',
                         options: {
    --- node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/typescript.js
    +++ node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/typescript.js
    @@ -65,7 +65,7 @@
             forkTypeChecker: buildOptions.forkTypeChecker,
             contextElementDependencyConstructor: require('webpack/lib/dependencies/ContextElementDependency'),
             logger: wco.logger,
    -        directTemplateLoading: true,
    +        directTemplateLoading: false,
             ...options,
         };
         pluginOptions = _pluginOptionsOverrides(buildOptions, pluginOptions);