0
votes

I'm building an Angular 10 Library to be published on a private NPM repository. Following Angular.io guide, I used ng new my-workspace --create-application=false and ng generate library my-library using Angular CLI.

I need to import RouterModule for one of the components, so I'm doing it like this:

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { MyLibraryComponent } from './my-library.component';

@NgModule({
  declarations: [MyLibraryComponent],
  imports: [
    RouterModule.forChild(null)
  ],
  exports: [MyLibraryComponent]
})
export class MyLibraryModule { }

When I try to build the library I get this error:

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

An unhandled exception occurred: Error during template compile of 'MyLibraryModule'
  Function calls are not supported in decorators but 'RouterModule' was called.

See "/tmp/ng-bGhmPt/angular-errors.log" for further details.

I tried to define the RouterModule.forChild() in a const variable to avoid the function call in the decorator, but it produces the same error:

import { ModuleWithProviders, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { MyLibraryComponent } from './my-library.component';

const routerModule: ModuleWithProviders<RouterModule> = RouterModule.forChild(null);

@NgModule({
  declarations: [MyLibraryComponent],
  imports: [routerModule],
  exports: [MyLibraryComponent],
})
export class MyLibraryModule {}

This error seems to be related to Ivy, as to build the library I'm using ng build --prod and Ivy is disabled for production. If I enable Ivy, removing this section from tsconfig.lib.prod.json

"angularCompilerOptions": {
    "enableIvy": false
}

then it builds successfully but I can't publish it to NPM due to the following error:

ERROR: Trying to publish a package that has been compiled by Ivy. This is not allowed.
Please delete and rebuild the package, without compiling with Ivy, before attempting to publish.

How should I import RouterModule (forChild) in a Library to be build without Ivy?

1

1 Answers

0
votes

Well, after some hours of testing and searching I found this Angular Issue that is related to this problem.

I totally agree with the last comment from @MickL; if this is an issue related to View Engine, it has been more than 2.5 years without a solution. If there will never be a solution for this, an official workaround should be posted in Angular documentation as long as View Engine is required to publish a library.

For now, it seems that the easier workaround is just as simple as use a constant before the decorator, and use that value in the decorator, as I stated before; all I was missing was an export.

import { ModuleWithProviders, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { MyLibraryComponent } from './my-library.component';

export const routerModule: ModuleWithProviders<RouterModule> = RouterModule.forChild(null);

@NgModule({
  declarations: [MyLibraryComponent],
  imports: [routerModule],
  exports: [MyLibraryComponent],
})
export class MyLibraryModule {}

I really hope this is fixed or at least covered by docs in Angular.