FileReplacements vs переменные среды - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть случай, когда я должен иметь возможность развернуть свой проект Angular 6 для двух разных серверов, каждый с немного отличающимся API, и т.д. По этой причине я добавил разные уровни абстракции в виде сервисов, чтобы интерфейс оставался равным интерфейсу.

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

app/
├── core/
│   ├── Server1.user.service.ts
│   ├── Server2.user.service.ts
│   ├── Server1.data.service.ts
│   ├── Server2.data.service.ts
│   └── ...
├── components/
│   ├── ...
│   └── ...
└── ...

Чего я хочу избежать, так это большого количества if (deployedForServer1) {...} в моем коде, так как это сложно поддерживать и сложно поддерживать обзор.

Теперь я не уверен, как лучше всего это реализовать.

Моим первым подходом было бы сделать это, заменив службы на "fileReplacements" в angular. json. Преимущество этого заключается в том, что будет развернут только нужный мне код, но в результате получается довольно сложная конфигурация angular. json.

Другим способом было бы работать с переменными среды, но здесь я не уверен, смогу ли я избежать использования в своем коде нескольких if (deployedForServer1) {...} -подобных запросов.

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

1 Ответ

1 голос
/ 18 февраля 2020

Вторая реализация if(deployedForServer1) { ... } неверна и станет абсолютным кошмаром для обслуживания. Если что-то изменится, например, новый адрес API или новый порт, вам потребуется изменить код и развернуть новую рабочую версию. Кроме того, он очень плохо масштабируется. Если вы хотите развернуть приложение на 5 других серверах, вам необходимо добавить это в коде.

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

Вы можете создать службу:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';

@Injectable({
    providedIn: 'root'
})
export class AppConfigService {
    constructor(
        private http: HttpClient
    ) { }

    private appSettings: any = {};

    setAppConfig() {

        if(environment.production) {
            return this.http.get('config.json')
                .toPromise()
                .then(apiKeys => {
                    this.appSettings = apiKeys;
                })
                .catch(error => {
                    console.error(error)
                    return Promise.reject();
                })
        } else {
            this.appSettings = environment.configToApi;
            return Promise.resolve();
        }

    }

    getAppSettings() {
        return this.appSettings;
    }
}

Затем вы вызовете функцию setAppConfig() в вашем app.module, используя APP_INITIALIZER:

{
          provide: APP_INITIALIZER,
          useFactory: (appConfig: AppConfigService) => {
              return () => {
                  return appConfig.setAppConfig();
              }
          },
          multi: true,
          deps: [AppConfigService]
}

You см. служба читает локальный файл config.json, в котором хранятся указанные c конфигурации сервера:

{
    "apiAddress": "...",
    "apiAddress2": "..."
}

Конфигурация хранится в объекте appSettings в службе, и вы можете получить доступ к Конфигурация в любое время, позвонив по номеру getAppSettings().

Преимущества этого подхода:

  1. Вы создаете только один раз и можете развертывать везде
  2. Конфигурация установлена во время выполнения, а не во время сборки. Это означает, что любая конфигурация сервера может быть изменена без сборки / развертывания новой версии.
...