You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

导入Angular库时APP_BOOTSTRAP_LISTENER注入令牌被重命名失效

问题

我用ng-packagr创建了名为NgxTest的测试库,该库使用APP_BOOTSTRAP_LISTENER注入令牌,代码如下:

import { APP_BOOTSTRAP_LISTENER, ComponentRef, NgModule } from "@angular/core";

@NgModule()
export class NgxTest { 
    static forRoot() {
        console.log(APP_BOOTSTRAP_LISTENER)
        return {
            ngModule: NgxTest,
            providers: [{
                provide: APP_BOOTSTRAP_LISTENER,
                useFactory: async (c: ComponentRef<any>) => {},
                multi: true,
              }]
        };
    }
}

将该库导入Angular项目时出现问题:我在app.config.ts中通过importProvidersFrom(NgxTest.forRoot())加载库配置:

import { ApplicationConfig, importProvidersFrom, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';
import { NgxTest } from 'ngx-test';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }), 
    provideRouter(routes),
    importProvidersFrom(NgxTest.forRoot()),
  ]
};

以该方式导入时,APP_BOOTSTRAP_LISTENER注入令牌被从InjectionToken重命名为InjectionToken2,导致其在启动阶段无法执行,请问该如何解决?

解决方案

这个问题源于Angular独立模式与NgModule模式的令牌解析冲突,加上ng-packagr打包时可能产生的重复令牌实例问题,可通过以下方法解决:

1. 为库添加独立模式兼容的提供者函数

放弃在独立配置中使用importProvidersFrom加载NgModule的forRoot,改为在库中直接提供独立模式可用的提供者函数:
在NgxTest库中新增文件src/lib/providers.ts:

import { APP_BOOTSTRAP_LISTENER, ComponentRef } from "@angular/core";

export function provideNgxTest() {
  return [
    {
      provide: APP_BOOTSTRAP_LISTENER,
      useFactory: async (c: ComponentRef<any>) => {
        // 此处编写你的启动监听逻辑
      },
      multi: true,
    }
  ];
}

在库的public-api.ts中导出该函数,然后在项目的app.config.ts中直接使用:

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideNgxTest } from 'ngx-test';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }), 
    provideRouter(routes),
    ...provideNgxTest(), // 直接展开提供者数组
  ]
};

2. 确保Angular依赖版本完全一致

检查库和项目的package.json,将Angular核心依赖设为peerDependencies而非dependencies,避免重复引入:
库的package.json配置示例:

{
  "peerDependencies": {
    "@angular/core": "^17.0.0"
  }
}

这样能保证项目与库使用同一版本的Angular核心代码,避免出现多个InjectionToken实例。

3. 调整ng-packagr打包配置

在库的ng-package.json中添加配置,防止打包时嵌入Angular核心模块:

{
  "$schema": "./node_modules/ng-packagr/ng-package.schema.json",
  "dest": "./dist/ngx-test",
  "lib": {
    "entryFile": "src/public-api.ts"
  },
  "allowedNonPeerDependencies": [],
  "preserveSymlinks": true
}

内容的提问来源于stack exchange,提问作者Usche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 16:07:40