Использование NgRx (с библиотекой ngrx-actions) в библиотеке Angular 6 - PullRequest
0 голосов
/ 06 сентября 2018

Я пытаюсь разделить приложение Angular с несколькими модулями на несколько (отдельных) библиотек Angular (используя это руководство ), поэтому я могу использовать эти библиотеки в нескольких приложениях Angular.
В настоящее время проект имеет несколько модулей, например:

  • Один для аутентификации / авторизации;
  • Один, содержащий все виды компонентов таблицы
  • Содержит все виды компонентов фильтра
  • Один, содержащий все виды компонентов диаграммы
  • ... (Я думаю, вы поняли) ...

Я начал работать над «преобразованием» модуля аутентификации / авторизации в библиотеку, потому что ожидал, что это будет самый сложный и сложный модуль.
Прямо сейчас я сталкиваюсь с некоторыми проблемами, которые я объясню ниже.

Модуль (в том виде, в котором он существует в настоящее время) использует NgRx в сочетании с действиями ngrx для уменьшения шаблонов. Как уже упоминалось (в руководстве ), создана библиотека и приложение для тестирования библиотеки. Я скопировал все содержимое существующего модуля в папку библиотеки.

Пришлось внести некоторые коррективы, потому что существующий модуль считывает некоторые константы из environment.ts и global.ts, которые (вероятно) не будут существовать, когда он используется в качестве библиотеки.

Прямо сейчас моя структура папок выглядит следующим образом, чтобы дать больше контекста (убрал node_modules):

.
├── README.md
├── angular.json
├── e2e
│   ├── protractor.conf.js
│   ├── src
│   │   ├── app.e2e-spec.ts
│   │   └── app.po.ts
│   └── tsconfig.e2e.json
├── package-lock.json
├── package.json
├── projects
│   ├── auth-lib
│   │   ├── karma.conf.js
│   │   ├── ng-package.json
│   │   ├── ng-package.prod.json
│   │   ├── package-lock.json
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── lib
│   │   │   │   ├── auth-check
│   │   │   │   │   ├── auth-check.component.html
│   │   │   │   │   └── auth-check.component.ts
│   │   │   │   ├── auth-guard.service.ts
│   │   │   │   ├── auth-routing.module.ts
│   │   │   │   ├── auth.module.ts
│   │   │   │   ├── auth.service.ts
│   │   │   │   ├── callback
│   │   │   │   │   ├── callback.component.ts
│   │   │   │   │   └── callback.html
│   │   │   │   ├── interceptors
│   │   │   │   │   └── auth.interceptor.ts
│   │   │   │   ├── permission-guard.service.ts
│   │   │   │   ├── signin
│   │   │   │   │   └── signin.component.ts
│   │   │   │   └── store
│   │   │   │       ├── auth-state.interface.ts
│   │   │   │       ├── auth.actions.ts
│   │   │   │       ├── auth.effects.ts
│   │   │   │       ├── auth.reducers.ts
│   │   │   │       └── auth.store.ts
│   │   │   ├── public_api.ts
│   │   │   └── test.ts
│   │   ├── tsconfig.lib.json
│   │   ├── tsconfig.spec.json
│   │   └── tslint.json
├── src
│   ├── app
│   │   ├── app.component.css
│   │   ├── app.component.html
│   │   ├── app.component.spec.ts
│   │   ├── app.component.ts
│   │   └── app.module.ts
│   ├── assets
│   ├── browserslist
│   ├── environments
│   │   ├── environment.prod.ts
│   │   └── environment.ts
│   ├── favicon.ico
│   ├── index.html
│   ├── karma.conf.js
│   ├── main.ts
│   ├── polyfills.ts
│   ├── styles.css
│   ├── test.ts
│   ├── tsconfig.app.json
│   ├── tsconfig.spec.json
│   └── tslint.json
├── tsconfig.json
└── tslint.json

public_api.ts содержит следующий код:

/*
 * Public API Surface of auth-lib
 */

export * from './lib/auth.module';
export * from './lib/auth-guard.service';
export * from './lib/permission-guard.service';
export * from './lib/auth.service';

auth.module.ts содержит следующий код:

import {NgModule} from '@angular/core';
import {SigninComponent} from './signin/signin.component';
import {AuthRoutingModule} from './auth-routing.module';
import {CallbackComponent} from './callback/callback.component';
import {AuthService, InternalAuthService} from './auth.service';
import {HTTP_INTERCEPTORS} from '@angular/common/http';
import {AuthInterceptor} from './interceptors/auth.interceptor';
import {AuthEffects} from './store/auth.effects';
import {EffectsModule} from '@ngrx/effects';
import {AuthStore} from './store/auth.store';
import {AuthCheckComponent} from './auth-check/auth-check.component';
import {NgrxActionsModule} from 'ngrx-actions/dist';
import {StoreRouterConnectingModule} from '@ngrx/router-store';

@NgModule({
  declarations: [
    SigninComponent,
    CallbackComponent,
    AuthCheckComponent
  ],
  imports: [
    AuthRoutingModule,
    NgrxActionsModule.forRoot({auth: AuthStore}),
    EffectsModule.forFeature([AuthEffects]),
  ],
  providers: [
    AuthService,
    InternalAuthService,
    {provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
    StoreRouterConnectingModule,
  ],
  exports: [],
})
export class AuthModule {

}

ПРИМЕЧАНИЕ: это работает, когда модуль существует внутри проекта (не как библиотека).
К вашему сведению: различные компоненты отправляют некоторые действия, такие как перенаправление на страницу регистрации (Auth0).

Тогда .. когда я хочу импортировать AuthModule в app.module.ts («тестовое приложение»), я получаю следующую ошибку, которую не могу устранить.

Error: StaticInjectorError(AppModule)[NgrxActionsModule -> ReducerManager]: 
  StaticInjectorError(Platform: core)[NgrxActionsModule -> ReducerManager]: 
    NullInjectorError: No provider for ReducerManager!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:1062)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1244)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1244)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
    at resolveNgModuleDep (core.js:8376)
    at _createClass (core.js:8429)
    at _createProviderInstance (core.js:8393)

Я видел эту проблему GitHub и этот вопрос переполнения стека , оба предлагали один и тот же ответ, но они не работают в моем случае.

Есть ли кто-нибудь, кто знает, как решить эту проблему? Спасибо!

1 Ответ

0 голосов
/ 07 сентября 2018

Предложений на странице переполнения стека и странице проблемы GitHub, о которых я упоминал в моем предыдущем посте, было недостаточно, чтобы решить эту проблему, но помог мне «решить» проблему или хотя бы немного продвинуться дальше.

При импорте StoreModule.forRoot({}) будет выдано другое исключение:

Error: StaticInjectorError(AppModule)[AuthEffects -> Actions]: 
  StaticInjectorError(Platform: core)[AuthEffects -> Actions]: 
    NullInjectorError: No provider for Actions!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:1062)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1244)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1244)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
    at resolveNgModuleDep (core.js:8376)
    at _createClass (core.js:8425)
    at _createProviderInstance (core.js:8393)

После импорта EffectsModule.forRoot([]) будет возвращено следующее исключение:

Error: StaticInjectorError(AppModule)[StoreRouterConnectingModule -> Router]: 
  StaticInjectorError(Platform: core)[StoreRouterConnectingModule -> Router]: 
    NullInjectorError: No provider for Router!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:1062)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1244)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1244)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
    at resolveNgModuleDep (core.js:8376)
    at _createClass (core.js:8425)
    at _createProviderInstance (core.js:8393)

При импорте RouterModule.forRoot([]) это будет (наконец-то) работать!
Мой auth.module.ts теперь выглядит так:

import {NgModule} from '@angular/core';
import {SigninComponent} from './signin/signin.component';
import {AuthRoutingModule} from './auth-routing.module';
import {CallbackComponent} from './callback/callback.component';
import {AuthService, InternalAuthService} from './auth.service';
import {HTTP_INTERCEPTORS} from '@angular/common/http';
import {AuthInterceptor} from './interceptors/auth.interceptor';
import {AuthEffects} from './store/auth.effects';
import {EffectsModule} from '@ngrx/effects';
import {AuthCheckComponent} from './auth-check/auth-check.component';
import {StoreRouterConnectingModule} from '@ngrx/router-store';
import {StoreModule} from '@ngrx/store';
import {RouterModule} from '@angular/router';
import {NgrxActionsModule} from 'ngrx-actions/dist';
import {AuthStore} from './store/auth.store';
import {StoreDevtoolsModule} from '@ngrx/store-devtools';

@NgModule({
  declarations: [
    SigninComponent,
    CallbackComponent,
    AuthCheckComponent
  ],
  imports: [
    RouterModule.forRoot([]),
    AuthRoutingModule,
    StoreModule.forRoot({}),
    NgrxActionsModule.forRoot({auth: AuthStore}),
    EffectsModule.forRoot([]),
    EffectsModule.forFeature([AuthEffects]),
    StoreRouterConnectingModule,
  ],
  providers: [
    AuthService,
    InternalAuthService,
    {provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
  ],
  exports: [],
})
export class AuthModule {
}

Одна вещь, которую я должен проверить прямо сейчас, это то, смогу ли я добавить состояния и маршруты в приложение Angular, которое импортирует библиотеку auth, из-за импорта нескольких операторов forRoot с пустым массивом в библиотеке. Я обновлю этот пост после того, как проверил это!

...