Рубрики
Uncategorized

Построить после развертывания в нескольких средах 🚀

В нашем стремлении построить приложение для двенадцати факторов, в котором мы строим один раз и развернуто в нескольких средах, мы столкнулись с некоторыми проблемами, но нам удалось решить их. Читайте здесь, как мы это сделали. Теги с угловым, дежоптом, CICD, Teadercript.

Приложение для двенадцати факторов

Если мы посмотрим на описание такого приложения, он говорит:

В современной эпохе программное обеспечение обычно поставляется в качестве сервиса: называется веб-приложениями или программным обеспечением — AS-A-A-Service. Приложение Twelve-Factor — это методология для создания программного обеспечения AS-A-сервисных приложений, которые:

  • Используйте декларативные форматы для автоматизации настройки, чтобы минимизировать время и стоимость новых разработчиков, присоединяющихся к проекту;
  • Иметь чистый договор с базовой операционной системой, обеспечивая максимальную переносимость между средами исполнения;
  • Подходят для развертывания на современных облачных платформах, усугубляя необходимость в администрации серверов и систем;
  • Минимизируйте расхождение между развитием и производством, обеспечивая постоянное развертывание для максимальной ловкости;
  • И может масштабировать без существенных изменений в инструменты, архитектуре или практике развития. Методология двенадцати факторов может применяться к приложениям, написанным на любом языке программирования, и которые используют любую комбинацию поддерживающих сервисов (базы данных, очередь, кэш памяти и т. Д.).

Приложение Twelve-Factor имеет 12 факторов, поскольку имени подразумевает, для этого поста мы считаем пятую тему Построить, освободить, запустить Отказ Если мы посмотрим на описание этого этапа, он говорит:

Кодовая база преобразована в (неразвивающее) развертывание через три этапа:

  • Стадия сборки Это преобразование, которое преобразует код REPO в исполняемый пучок, известный как сборку. Используя версию кода при коммитке, указанном процессом развертывания, этап сборки выбирает зависимости поставщиков и компилирует двоичные базы и активы.
  • Этап выпуска Принимает сборку изготовленной на этапе сборки и сочетает в себе его с текущей конфигурацией развертывания. Полученный выпуск содержит как сборку, так и конфигурацию и готов к немедленному исполнению в среде выполнения.
  • Run Stage (Также известный как «Runtime») запускает приложение в среде выполнения, запустив некоторые набор процессов приложения для выбранного выпуска. Код становится сборкой, который сочетается с конфигурацией для создания выпуска.

Приложение Twelve-Factor использует строгое разделение между этапами сборки, выпуска и прогона. Например, невозможно внести изменения в код во время выполнения, поскольку нет способа распространять эти изменения обратно на этап сборки.

окружающая среда

Я считаю, что этот файл пропускается в большинстве случаев, может быть, даже самый миссионный файл в угловом приложении. На мой взгляд, угловые должны быть более явными в использовании этого файла. К сожалению, мы не были исключения, и мы не знали этого до некоторого времени назад. Наши файлы окружающей среды имели некоторые переменные конфигурации внутри них, которые варьировались между средами, например Конечная точка API или токен для использования 3-го вечеринки. Это вызвало нас создать отдельный окружающая среда Файл для каждой среды Dev, Test, постановка, производство1 и Production2. Сохраняя наши переменные конфигурации в окружающая среда Файлы заставили нас создать приложение для каждой среды, когда нам нужно было развернуть новую версию нашего приложения. Это было трудоемкость, и это также было подвержено ошибкам. Коротко сказал, это считается плохой практикой.

В качестве начала нашего квеста мы извлекли все переменные определенные среды в файл конфигурации, который является просто простым файлом json. Это оставило нас 2 окружающая среда Файлы определить, если это создание производства или нет. Они будут знакомы, поскольку они также являются файлами по умолчанию, предоставляемыми угловыми.

// environment.ts
export const environment = {
  production: false,
}
// environment.prod.ts
export const environment = {
  production: true,
}

Хотя мы разрабатываем приложение, которое мы используем окружающая среда Файл, когда мы создаем сборку на нашем сервере CI, мы используем окружающая среда файл. Угловая CLI поднимает правильный файл через angular.json файл.

Развертывание приложения

Теперь, как мы должны развернуть в среду с правильными переменными конфигурации? Для этого нам придется переопределить файл конфигурации во время развертывания. В зависимости от инфраструктуры и инструментов, которые вы используете, вы можете либо заменить файл конфигурации правильным, или вы можете определить переменные конфигурации во время шага развертывания и переопределить каждую переменную конфигурации с установленной переменной.

Теперь у нас есть одна сборка и несколько развертываний, но мы все еще должны загружаться в файл конфигурации в нашем приложении. Это часть, куда мы немного боролись.

Использование файла конфигурации

Мы думали, что мы не были первыми в этом квесте, поэтому мы отправились в Интернете, чтобы решить нашу проблему. Все решения, которые мы столкнулись, использовали App_initializer Поставщик, чтобы отложить процесс загрузки угловых компонентов до тех пор, пока не был загружен конфигурационный файл.

export function initConfig(configService: AppConfigService) {
  return () => configService.init() // in this function the config file is being loaded
}

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initConfig,
      deps: [AppConfigService],
      multi: true,
    },
  ],
})
export class AppModule {}

Для получения дополнительной информации и полного примера реализации я настоятельно рекомендую Jurri llumplohner. Блог Время компиляции vs. Конфигурация времени выполнения вашего углового приложения

Сначала это казалось хорошим решением и после его реализации, он сделал то, что он должен делать, и это сработало. Мы были счастливы.

До тех пор, пока нам нужно было получить доступ к нашему конфигуру от внешних компонентов и услуг, у нас были другие объекты конфигурации в зависимости от файла конфигурации при запуске. Нам нужно было создать объект конфигурации для загрузки модуля, пример в том, что нам нужно для загрузки PhicientInsiteSModule при запуске. Мы пытались цепи несколько App_initializer Поставщики в надежде, что нам не пришлось начать все сначала. К сожалению, мы обнаружили, что конфигурация не загружена в то время, когда нам это нужно. Мы пробовали несколько способов обойти его без изменения нашего решения с App_initializer Поставщик, но без какого-либо успеха.

Итак, мы вернулись к чертежной доске и попросили некоторую помощь в Angularindepth Группа, где Joost Koehoorn и Ларс Gyrup Brink Nielsen предложил несколько великолепных руководств. С некоторой помощью мы обнаружили, что PlatformBrowserdynamic также принимает провайдеров.

PlatformBrowserdynamic

Нам нужно было загружать переменные конфигурации перед загрузкой приложения, чтобы сделать это, мы сделали процесс загрузки на шаг дальше. Нам сначала пришлось загрузить файл конфигурации, прежде чем все остальное, прежде чем приложение было загружено. Угловые ботинки вверх по приложению модуль внутри Main.ts файл. Для решения нашей проблемы нам пришлось отложить этот процесс, пока мы не загрузим наши переменные конфигурации. Потому что PlatformBrowserdynamic Принимает провайдеров, мы увидели возможность определить здесь конфигурацию.

Код ниже загружает файл конфигурации через Fetch API Отказ Это обещание, поэтому мы можем точно знать, что конфигурационный файл будет загружен до того, как мы загрузим модуль приложений. Самообъявленный App_config Здесь используется токен для хранения переменных конфигурации.

fetch('/assets/config.json')
  .then(response => response.json())
  .then(config => {
    if (environment.production) {
      enableProdMode()
    }

    platformBrowserDynamic([{ provide: APP_CONFIG, useValue: config }])
      .bootstrapModule(AppModule)
      .catch(err => console.error(err))
  })

Использование App_config.

Теперь мы шаг вперед, мы загрузили конфигурацию, прежде чем загрузовать приложение, но мы все еще должны использовать его. Как последнее препятствие в нашем квесте, мы должны были создать PhicientInsiteSModule конфиг. Потому что мы знаем, что файл конфигурации загружен, когда AppModule Загружено, теперь мы можем получить доступ к файлу конфигурации и предоставить конфигурацию приложений Insights. Также хорошо повторно использовать App_config CONFIG, но чтобы сделать конфигурацию более выплавленным и поддерживаться для модулей, мы раздуваем большую конфигурацию на меньшие куски.

@NgModule({
  providers: [
    {
      provide: APP_INSIGHTS_CONFIG,
      useFactory: (config: AppConfig) => config.applicationInsights,
      deps: [APP_CONFIG],
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Упаковка

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

В качестве бонуса на такого рода установка делает его очень легко создавать и использовать функцию переключения.

TLDR:

  • Не используйте окружающая среда Файл для определения определенной среды Config переменные, создайте пользовательский файл конфигурации (как json) большую часть времени, используя
  • App_initializer Подход станет решением этой проблемы используя
  • PlatformBrowserdynamic Подход решает эту проблему по-другому (а также легче понять, когда вы не знакомы с процессом Bootstrap?)

Оригинал: «https://dev.to/angular/build-once-deploy-to-multiple-environments-3nnf»