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

3

12

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

Woofer answered 27/3, 2018 at 9:43 Comment(6)
BsDropdownModule is in node_modules/angular-library-name/free/dropdown You have to npm install to see it. This module is after compilation to js.Woofer
Sorry, my bad. Please try now, I've added angular-library-name-5.2.3.tgz file and added it to dependencies. Download fresh repo and type npm iWoofer
@yurzui could you describe this using more words?Woofer
Okay I'll test it and let you know if it's working or not.Woofer
It was something else. I had to point exact path for some providers. For example not import { service } from './services' but import { service } from './services/sample.service. But thanks for your help!Woofer
I'm facing the same problem. Did you only remote the index.ts from the services folder or from all the components?Aliciaalick
T
2

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

Truehearted answered 8/10, 2018 at 13:40 Comment(0)
W
0

Your forRoot method should return ModuleWithProviders and annotated with @NgModule

  import { ModuleWithProviders, NgModule } from '@angular/core';

    @NgModule({
        declarations: [],
        imports: [],
        providers: [],

      })
    export class BsDropdownModule {
       // constructor(parentModule: BsDropdownModule);
        //  static forRoot(config?: any): ModuleWithProviders;
        static forRoot(config?: any): ModuleWithProviders {

            return {
                ngModule: BsDropdownModule,
                providers: [
                ]
            }
        }
    }

So, you should import dropdown.module in app.module not the declaration file dropdown.module.d.ts

import { BsDropdownModule } from './dropdown.module';


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

I tested with AOT build. No error

Watertight answered 27/3, 2018 at 11:38 Comment(3)
The code you entered is included in the module which is not yet compiled to .js. The compiled module only contains the code that I've pasted, and for some reason the code doesn't work after compilation - it throws away an error that I've pasted above. Please check my dropdown.module.ts code which I've posted above.Woofer
import { BsDropdownModule } from 'angular-library-name'; Is it dropdown.module.ts ? angular-library-nameWatertight
import { BsDropdownModule } from 'angular-library-name'; is compiled to js module. While importing this module to my app.module, I'm unable to call forRoot() method on it while AOT. If something isn't clear to you, maybe try to download my repo and look at code?Woofer
P
-1

I am facing the same issue as well, I was able to narrow it to ng-packagr. I extracted my module out of the library and tested in separate application I didn't face any AOT errors. I only get this error when I package my module in a library

I am using Angular 6.1.8 and ng-packagr 4.2.0

Pruitt answered 25/9, 2018 at 21:27 Comment(1)
This doesn't solve the problem. I know you don't have earned the commentary privilege, but this doesn't help to solve the problemDelora

© 2022 - 2024 — McMap. All rights reserved.