Массовые проблемы при добавлении библиотеки Angular 7 для REST API среднего размера
Я создаю приложение, которое должно взаимодействовать с внутренним REST API. Это приложение имеет несколько проектов пользовательского интерфейса, которые у меня есть как отдельные приложения Angular, так и библиотека управления. Всем этим компонентам необходим доступ к REST API.
Я генерирую Angular-совместимый SDK, используя Swagger CodeGen. Это прекрасно работает; но я бы предпочел не иметь три копии кода во всех трех проектах пользовательского интерфейса; я хотел бы создать библиотеку ngx-sdk, которая содержит ссылку на сгенерированный Angular, а затем упаковать ее через NPM и сделать ее доступной для трех проектов Angular. Это похоже на случай использования Slam Dunk для библиотек Angular, поэтому я попробовал.
Я могу использовать инструкции онлайн, чтобы создать стандартную библиотеку, собрать ее, упаковать и сделать ее доступной через NPM. Проблема возникает, когда я пытаюсь загрузить свой REST-код в библиотеку.
Во-первых, способ, которым Swagger генерирует код, на самом деле это 4 разных "набора" API. Таким образом, если я создаю банковское приложение и у меня есть служба кассира, служба учета и служба поддержки клиентов, то Swagger создаст три каталога для каждого. Нет проблем, мне это нравится. Так что в моем основном угловом коде я хотел бы иметь доступ к такой службе:
import {Teller,TellerTransactionsWindowService} from '@acmesoftware/tellers'
import {Account,ExchangeRateService} from '@acmesoftware/accounts'
Библиотеки Angular, кажется, борются с этой концепцией, хотя после некоторого поиска я обнаружил концепцию вторичных точек входа, которая, кажется, является тем, что я ищу. Я использовал этот пост, чтобы настроить точки входа:
библиотека angluar-cli создает вторичную точку входа
Похоже, ng-packr очень чувствителен к разметке каталогов. Итак, я просто пытаюсь настроить службу кассира... один раз за шагом. У меня есть это:
\---projects
\---scope
\---ngx-sdk
| karma.conf.js
| ng-package.json
| ng-package.prod.json
| package.json
| tsconfig.lib.json
| tsconfig.spec.json
| tslint.json
|
\---src
| public_api.ts
| test.ts
|
+---lib
| package-client-config.ts
| package-client.spec.ts
| package-client.ts
| package.module.ts
|
\---tellers
| index.ts (1)
| package.json (2)
| public_api.ts (3)
|
\---src
| public_api.ts (4)
|
\---lib
| ... generated code goes here
В каталоге lib находится весь коден от Swagger, включая файл tellers-api.module.ts, который ссылается на /api, /model и.configuration. Я указываю на это с помощью файла public_api.ts. Хорошо, пока все хорошо. Я строю, и вот что я получаю:
Building Angular Package
Building entry point '@acmesoftware/ngx-sdk'
Compiling TypeScript sources through ngc
Bundling to FESM2015
Bundling to FESM5
Bundling to UMD
Minifying UMD bundle
Copying declaration files
Writing package metadata
Removing scripts section in package.json as it's considered a potential security vulnerability.
Built @acmesoftware/ngx-sdk
Building entry point '@acmesoftware/ngx-sdk/src/tellers'
Compiling TypeScript sources through ngc
Bundling to FESM2015
Bundling to FESM5
Bundling to UMD
Minifying UMD bundle
Copying declaration files
Writing package metadata
Removing scripts section in package.json as it's considered a potential security vulnerability.
Built @acmesoftware/ngx-sdk/src/tellers
Built Angular Package!
- from: D:\acme\ngx-sdk\projects\ngx-sdk
- to: D:\acme\ngx-sdk\dist\ngx-sdk
Итак, сборка прошла успешно.
Вопрос 1: Кажется, он обнаруживает точку входа secpmdaru, но вместо того, чтобы монтировать ее в @acmesoftware/ngx-sdk/tellers, как я и ожидал, она помещает туда подкаталог src/. Это заставляет мое приложение Angular ссылаться так:
import {Teller,TellerTransactionsWindowService} from '@acmesoftware/src/tellers'
Не огромная сделка, но довольно странная и не очень предпочтительная.
Но настоящая проблема возникает, когда я пытаюсь импортировать модуль API, сгенерированный мной в Swagger, в мое потребляющее угловое приложение. Мой код выглядит так:
import {TellersApiModule} from '@acmesoftware/ngx-sdk/src/tellers';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
NgxSdkModule,
HttpClientModule,
TellersApiModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Затем в моем коде AppComponent у меня есть это:
import { Component } from '@angular/core';
import {Teller, TellerTransactionsWindowService} from '@rhythmsoftware/ngx-sdk/src/tellers';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'ngx-sample';
contact: Contact;
constructor( private tellersService: TellersService) {
this.tellersService.getTeller( id );
}
}
И как только я это делаю, я начинаю видеть ошибки, которых я никогда раньше не видел. Опять же, TellersService был автоматически сгенерированным кодом из кода Swagger, и он должен был сделать HTTP-вызов моей серверной REST-службе. Когда я создаю приложение, я получаю:
WARNING in ../ngx-sdk/node_modules/@angular/core/fesm5/core.js 17170:15-36
Critical dependency: the request of a dependency is an expression
chunk {main} main.js, main.js.map (main) 115 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 223 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.08 kB [entry] [rendered]
WARNING in ../ngx-sdk/node_modules/@angular/core/fesm5/core.js 17182:15-102
chunk {styles} styles.js, styles.js.map (styles) 16.3 kB [initial] [rendered]
Critical dependency: the request of a dependency is an expression
chunk {vendor} vendor.js, vendor.js.map (vendor) 5.62 MB [initial] [rendered]
Это предупреждения, но приложение выдает мне ЭТУ ошибку, которая приводит к сбою страницы:
main.js:2523 Error: StaticInjectorError(AppModule)[HttpHandler -> Injector]:
StaticInjectorError(Platform: core)[HttpHandler -> Injector]:
NullInjectorError: No provider for Injector!
at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (vendor.js:82974)
at resolveToken (vendor.js:83219)
at tryResolveToken (vendor.js:83163)
at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (vendor.js:83060)
at resolveToken (vendor.js:83219)
at tryResolveToken (vendor.js:83163)
at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (vendor.js:83060)
at resolveNgModuleDep (vendor.js:99530)
at _createClass (vendor.js:99577)
at _createProviderInstance (vendor.js:99547)
И это все... Я застрял. Я подумал, что, возможно, мне не хватает HttpClientModule, но он импортирован в app.module и должен быть доступен. Я не знаю, что он не может вводить и почему нет, и я застрял и зашел в тупик.
Любые мысли приветствуются!