Solvedangular Function calls are not supported in decorators when fullTemplateTypeCheck is not specified and @dynamic has no effect

I'm submitting a...

[X] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

When building a library and specifying both skipTemplateCodegen and strictMetadataEmit to true, and you try to call a method inside the ngModule decorate example RouterModule.forChild([]) this will cause a compilation error Function calls are not supported in decorators but 'RouterModule' was called.

When adding fullTemplateTypeCheck to true the error is not emitted.

Also, @dynamic seems not to have any effect in this particular case.

Expected behavior

No error emitted, or at least that it can be suppressed with the @dynamic.

I also expect that setting fullTemplateTypeCheck doesn't have any effect here as this flag relates more to binding in templates.

Minimal reproduction of the problem with instructions

Create a file example

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

@NgModule({
  imports: [
    RouterModule.forChild([])
  ]
})
export class LibModule { }

Have tsconfig set with the following options;

  "angularCompilerOptions": {
    "skipTemplateCodegen": true,
    "strictMetadataEmit": true
  }

When transpiling this will emit an error;

Error during template compile of 'LibModule' Function calls are not supported in decorators but 'RouterModule' was called.

Note when adding "fullTemplateTypeCheck": true no error is emitted. (Though this is kinda weird as I don't think this shouldn't have any effect)

Reproduction repo: https://github.com/alan-agius4/angular-issue-23609

What is the motivation / use case for changing the behavior?

No error was emitted in NG 5

Environment

Angular version: 6.0.0-rc-6

Related issues:
ng-packagr/ng-packagr#822
ng-packagr/ng-packagr#778
ng-packagr/ng-packagr#727
ng-packagr/ng-packagr#765
ng-packagr/ng-packagr#767
ng-packagr/ng-packagr#885

22 Answers

Ôťö´ŞĆAccepted Answer

Regarding Ward's repro: @wardbell

The build will succeed / fail depending on the combination of angularCompilerOptions. Added one example in this repro

Build success

    "skipTemplateCodegen": true,
    "strictMetadataEmit": true,
    "fullTemplateTypeCheck": true
    "skipTemplateCodegen": false,
    "strictMetadataEmit": false
    "skipTemplateCodegen": false,
    "strictMetadataEmit": true,
    // fullTemplateTypeCheck omitted (= default value)

Build failures

    "skipTemplateCodegen": true,
    "strictMetadataEmit": true,
    // fullTemplateTypeCheck omitted (= default value)
    "skipTemplateCodegen": true,
    "strictMetadataEmit": false
    // fullTemplateTypeCheck omitted (= default value)

Observation

In Ward's example, setting "skipTemplateCodegen": true requires that "fullTemplateTypeCheck": true is also enabled to get a success build from ngc.

Side notes / other thoughts

My experience is that the issue goes down to "everything statically analyzable for AoT" (see "need for static value resoltion" in the compiler docs). Imo, something is broken around the strictMetadataEmit option or my understanding of the option is horribly broken ­čść

From my experience I can tell that the issue is often produced in static forRoot(): ModuleWithProviders, sometimes depending on one line of code that becomes or becomes not "statically analyzable". Of course, I don't have reliable repros and I also don't want to speculate on some vague memories of code that I've seen working / non-working.

Can ngc improve the error message?

What will help that ngc prints out the line number in the source code that triggers the error.

Other Answers:

Can anyone tell a nub what should I do for now to workaround this issue?
ng build --prod
I'm using ngx-progressbar
and i get : "Function calls are not supported in decorators but 'NgProgressModule' was called."

I fixed that by replacing import of RouterModule.forChild(routes) with the previously defined constant:
export const routerModule = RouterModule.forChild(routes);

This has arguably been the most annoying error that libraries have had to deal with, and I'm glad that this class of issues has been resolved with the Ivy compiler.

With v12 now allowing libraries to be compiled with the Ivy compiler, I am closing this issue as resolved.

More Issues: