Angular 模块导入的动态配置

bar*_*azs 12 typescript intercom angular

我们的 Angular 12 应用程序有一个模块,该模块导入我们想要根据配置文件配置的依赖项,该配置文件在运行时可用,而在编译时不可用。

有问题的软件包是ng-intercom,尽管我想其他软件包稍后也会出现同样的问题。

动态配置背后的动机是我们的应用程序在 4 个不同的环境中运行,我们不想为每个环境创建单独的构建,因为它们之间的唯一区别是包含后端 URL 和一些应用程序 ID 的配置文件(例如对讲机、Facebook 应用 ID 等)

这就是目前所讨论的导入方式:

imports: [
  ...
  IntercomModule.forRoot({
    appId: env.intercomID,
    updateOnRouterChange: true,
  }),
  ...
Run Code Online (Sandbox Code Playgroud)

问题是appID 应该是可配置的,env 变量应该动态加载。目前,它是导入并编译到代码中的 JSON,但这意味着我们无法在不同环境中更改它,而不为每个环境重新构建代码:

import env from '../../assets/environment.json';
Run Code Online (Sandbox Code Playgroud)

然而,我们有一个APP_INITIALIZER,它不会阻止模块在解析之前被导入:

{
  provide: APP_INITIALIZER,
  useFactory: AppService.load,
  deps: [AppService],
  multi: true,
},
Run Code Online (Sandbox Code Playgroud)

...以及相关的配置加载器:

static load(): Promise<void> {
  return import('../../assets/environment.json').then((configuration) => {
    AppService.configSettings = configuration;
  });
}
Run Code Online (Sandbox Code Playgroud)

我们可以使用此配置,而我们的组件和服务不会出现问题。

我们设法在angularx-social-login的配置中实现了我们想要的结果:

providers: [
  ...
  {
    provide: 'SocialAuthServiceConfig',
    useValue: new Promise(async resolve => {
      const config = await AppService.config();
      resolve({
        autoLogin: true,
        providers: [
          {
            id: FacebookLoginProvider.PROVIDER_ID,
            provider: new FacebookLoginProvider(config.facebookApi),
          }
        ]
    } as SocialAuthServiceConfig);
  ...
]
Run Code Online (Sandbox Code Playgroud)

SocialAuthServiceConfig 是一个提供程序,但是我们找不到类似地配置 ng-intercom 导入的方法。

我们能以某种方式实现这一目标吗?有没有办法动态配置模块导入?

Ame*_*mer 5

我认为不需要动态配置模块导入来实现这一点,相反,您可以执行以下操作:

  • 导入IntercomModule不带该forRoot功能的。
  • 提供IntercomConfig使用useFactory从以下位置读取数据配置的函数的类AppService.configSettings
  providers: [
    {
      provide: IntercomConfig,
      useFactory: intercomConfigFactory,
    },
  ],

// ....

export function intercomConfigFactory(): IntercomConfig {
  return {
    appId: AppService.configSettings.intercomAppId,
    updateOnRouterChange: true,
  };
}
Run Code Online (Sandbox Code Playgroud)