Фабрика APP_INITIALIZER вообще не работает при настройке в библиотеке Angular

#angular

#angular

Вопрос:

Пример кода в библиотеке:

 export function appSettingsLoader(): () => Promise<unknown> {
  console.log('i should run first')
  const func = function () { return Promise.Resolve()) };
  return func;
}

@NgModule({
  imports: [
    MsalModule
  ]
})
export class MsalAuthenticationModule {
  public static forRoot(options: {
    config: Type<IMsalConfigurationService>
  }): ModuleWithProviders {
    return {
      ngModule: MsalAuthenticationModule,
      providers: [
        {
          provide: APP_INITIALIZER,
          useFactory: appSettingsLoader,
          deps: [],
          multi: true
        }
      ]
    };
  }
}
  

Код в модуле приложения:

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

Я никогда не увижу свой console.log.

Редактировать:

из комментариев я решил попробовать воспроизвести новое приложение angular с библиотекой внутри того же приложения в разделе «Проекты». К моему удивлению, app_initializer сработал.

Поэтому я затем использовал NPM Link в этой рабочей библиотеке и импортировал оттуда модуль в свое реальное приложение (другое рабочее пространство). Это не сработало.

Это говорит мне о том, что app_initializer может работать только тогда, когда библиотека находится внутри того же проекта, что делает app_initializer бесполезным для меня.

Это кажется неправильным, но это то, что я заметил.

Комментарии:

1. Я вижу, что у вас есть useFactory: appSettingsLoader, , но appSettingsLoader это функция, которая выполняется только при вызове, возможно, вызывая ее как appSettingsLoader() ?

2. @Craig вы могли бы поделиться MVP в репозитории? Похоже, это работает, по крайней мере, для приложения.

3. Взгляните на рабочий stackblitz: stackblitz.com/edit/angular-8-getting-started-w9krjn

4. Вы видите какую-либо ошибку на консоли?

5. Пожалуйста, смотрите Мое редактирование для получения более подробной информации

Ответ №1:

Проблема возникает из-за объединения нескольких модулей — библиотека получила неправильный каталог для модулей angular node (использовала папку node_modules рабочего пространства библиотеки), даже при использовании ее через npm link для имитации публикации.

Добавлено это в мое клиентское приложение, которое использует библиотеку в параметрах компиляции tsconfig:

 "paths": {
  "@angular/*": [
    "./node_modules/@angular/*"
  ]
}
  

проблема решена.

Очевидно, что библиотека должна использовать точно такие же модули узла, чтобы подключаться к таким перехватчикам инициализации.

Редактировать:

У меня было еще больше проблем. Если у вас есть 2 app_initializers a и b, a является асинхронным, а b зависит от a, приложение не будет ждать разрешения a, и поэтому b будет выдавать ошибки. Чтобы решить эту проблему, я использовал инжектор в b.