Function calls are not supported in decorators while ng build --prod (AOT)

Bloodcast69 picture Bloodcast69 · Mar 27, 2018 · Viewed 9.1k times · Source

Type of Issue: Bug / Question

Description

I'm using ng-packagr lib to compile my library to js. I've compiled everything without any problems, but when I'll want to consume my library with ng build --prod (AOT enabled), I'm getting error:

ERROR in Error during template compile of 'AppModule' Function calls are not supported in decorators but 'BsDropdownModule' was called.

When I remove .forRoot method, I'm getting error:

ERROR in : Unexpected value 'BsDropdownModule in /home/sf/Desktop/Developerka/kompilacja/final/sample-repo/node_modules/angular-library-name/free/dropdown/dropdown.module.d.ts' imported by the module 'AppModule in /home/sf/Desktop/Developerka/kompilacja/final/sample-repo/src/app/app.module.ts'. Please add a @NgModule annotation

Please note, that ng --prod --aot=false is not producing any errors.

How To Reproduce:

Download repo: https://github.com/Bloodcast69/aot-error , type npm install ng build --prod.

Expected Behaviour

Want to build with AOT without errors (I need this to be compatible with Angular Universal) Version Information

ng-packagr: 2.4.1 @angular/*: 5.2.9 typescript: 2.5.3 rxjs: 5.5.6 node: 8.1.0 npm/yarn: npm: 5.6.0

Files:

app.module.ts:

import { BsDropdownModule } from 'angular-library-name';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';



import { AppComponent } from './app.component';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BsDropdownModule.forRoot(),
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

dropdown.module.d.ts:

import { ModuleWithProviders } from '@angular/core';
export declare class BsDropdownModule {
    static forRoot(config?: any): ModuleWithProviders;
}

dropdown.module.ts (before compilation to JS):

import { ModuleWithProviders, NgModule } from '@angular/core';
import { ComponentLoaderFactory } from '../utils/component-loader/index';

import { PositioningService } from '../utils/positioning/index';
import { BsDropdownContainerComponent } from './dropdown-container.component';
import { BsDropdownMenuDirective } from './dropdown-menu.directive';
import { BsDropdownToggleDirective } from './dropdown-toggle.directive';
import { BsDropdownConfig } from './dropdown.config';

import { BsDropdownDirective } from './dropdown.directive';
import { BsDropdownState } from './dropdown.state';

@NgModule({
  declarations: [
  BsDropdownMenuDirective,
  BsDropdownToggleDirective,
  BsDropdownContainerComponent,
  BsDropdownDirective
  ],
  exports: [
  BsDropdownMenuDirective,
  BsDropdownToggleDirective,
  BsDropdownDirective
  ],
  entryComponents: [BsDropdownContainerComponent]
})
export class BsDropdownModule {
  public static forRoot(config?: any): ModuleWithProviders {
    return {
      ngModule: BsDropdownModule, providers: [
      ComponentLoaderFactory,
      PositioningService,
      BsDropdownState,
      {provide: BsDropdownConfig, useValue: config ? config : {autoClose: true}}
      ]
    };
  };
}

NOTE I've read whole Internet to find something which would be helpful to me, but without any success. I've checked this topics:

FeatureModule fails during an AOT build when static forRoot has arguments

https://github.com/angular/angular/issues/14707

If there's missing some needed informations, please let me know, and I'll provide it.

Thanks, Bloodcast69

Answer

Alessio Stalla picture Alessio Stalla · Oct 8, 2018

It's a problem with AOT: the forRoot function needs to be executed at compile-time. On a more recent version of Angular it should work as-is, otherwise you might have luck playing with tsconfig.app.json. Check this related question: Angular 6 Prod Function calls are not supported in decorators but '..Module' was called