NullInjectorError: R3InjectorError(AppModule)[Router -> Router -> Router]: NullInjectorError: No provider for Router

And*_*ich 4 angular

我有一个已发布的库,其中包含一个在其模板中使用 [routerLink] 的组件。在我的应用程序中安装库后,我收到错误NullInjectorError: R3InjectorError(AppModule)[Router -> Router -> Router]: NullInjectorError: No provider for Router!

在库中的模块中,RouterModule 被导入,如下所示:

@NgModule({
  declarations: [
    Component
  ],
  exports: [
    Component
  ],
  imports: [
    CommonModule,
    RouterModule,
    TranslateModule
  ]
})
export class LibWithComponentModule {
}
Run Code Online (Sandbox Code Playgroud)

在我的应用程序中,RouterModule 配置如下:

const routes: Routes = [{
  path: '',
  component: RootComponent
}];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
Run Code Online (Sandbox Code Playgroud)

app.module.ts如下所示:

  declarations: [
    AppComponent,
    RootComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    LibWithComponentModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

但是我想会提供 RouterModule 吗?我究竟做错了什么?

Nil*_*gat 6

我正面临着您在我正在处理的大型应用程序中描述的完全相同的场景。我的主应用程序导入了一个已发布的 npm 组件包,其中包含一个利用该routerLink指令的组件。运行应用程序时,我遇到了R3InjectorError您提到的相同情况,即使RouterModule在需要它的所有模块中都正确导入。

The root cause of the problem in my case, was the fact that this npm package explicitly listed @angular/router as one of the dependencies instead of a peerDependency (which in the case of a library it should have been). This means @angular/router will be installed both in your node_modules, as well as in node_modules/LIBRARY/node_modules!

What happens is that at runtime, the RouterModule your published component uses has a different InjectionToken than the RouterModule your application provided using a RouterModule.forRoot(). The published component's RouterModule refers to node_modules/LIBRARY_NAME/node_modules/@angular/router, whereas the main application has provided the one in node_modules/@angular/router.

所以总而言之:解决方法是不@angular将您的库中的任何包明确列为dependency,而是正确地将它们标记为peerDependency. 这是从文档中管理依赖项的有趣读物ng-packagr

供参考:我不确定这是否与 Ivy 完全相关,但在我的场景中,我运行的是启用了 Ivy 的 Angular 11。

在这种情况下,错误消息肯定非常令人困惑,因为注入的服务被命名了Router两次,即使它们引用了不同的实例。

希望这也能解决您的问题,我花了很多时间来解决这个问题!