Micro-Frestend – это будущее веб-разработки переднего конца.
Вдохновленный микросервисами, которые позволяют расставлять свою бэкфон на меньшие кусочки, Micro-Frestends позволяет создавать, тестировать и развертывать кусочки вашего приложения Frontend независимо друг от друга.
В зависимости от Framework Micro-Frontend вы выбираете, вы даже можете иметь несколько приложений Micro-Frontend – написанные в React, Angular, Vue, или что-то еще – вообще сосуществуют в одном и том же приложении.
В этой статье мы собираемся разработать приложение, состоящее из микропрофилей, использующих Однопрограмма и развернуть его на Heroku Отказ
Мы настроим непрерывную интеграцию, используя Трэвис CI Отказ Каждый трубопровод CI будет объединять JavaScript для приложения Micro-Frontend, а затем загружать результирующие артефакты сборки на AWS S3 Отказ
Наконец, мы сделаем обновление до одного из приложений Micro-Frontend и посмотрим, как его можно развернуть до производства независимо от других приложений Micro-Frontend.
Прежде чем мы обсудим пошаговые инструкции, давайте получим быстрый обзор того, что составляет демонстрационное приложение. Это приложение состоит из четырех подпозначных приложений:
- А Контейнерное приложение Это служит главной страницей контейнером и координирует монтаж и размонтирование приложений Micro-Frontend
- А Micro-Frestend App Navbar App Это всегда присутствует на странице
- А Micro-Fressend “Page 1” Приложение Это только показывает когда активно
- А Micro-Frontend “Page 2” Приложение Это также только показывает, когда активен
Эти четыре приложения все живут в отдельных репос, доступных на GitHub, который я связал выше.
Конечный результат довольно прост с точки зрения пользовательского интерфейса, но, чтобы быть понятным, пользовательский интерфейс не является точкой здесь.
Если вы соблюдаете на собственной машине, к концу этой статьи у вас тоже будет вся базовая инфраструктура, необходимая для начала работы с собственным приложением Micro-Frontend.
Хорошо, возьми снарядую снаряжение, потому что пришло время нырять!
Чтобы генерировать приложения для этой демонстрации, мы собираемся использовать инструмент интерфейса командной строки (CLI) Create-Single-Spa Отказ Версия Create-Single-Spa на момент написания – 1.10.0, а версия Only-Spa, установленная через CLI, составляет 4.4.2.
Мы будем следовать этим шагам для создания приложения контейнера (также иногда называемого корневым конфигом):
mkdir single-spa-demo cd single-spa-demo mkdir single-spa-demo-root-config cd single-spa-demo-root-config npx create-single-spa
Затем мы будем следовать подсказкам CLI:
- Выберите «Однократный CORT CORF CONFIG»
- Выберите «пряжу» или «NPM» (я выбрал «пряжа»)
- Введите название организации (я использовал «Thakkin3», но это может быть то, что вы хотите)
Большой! Теперь, если вы проверите Однопроизводительный CORF-CONFIG Справочник, вы должны увидеть приложение CORF CONFIC SKEELTON CORF. Мы будем настроить это немного, но сначала будем использовать инструмент CLI для создания наших трех других приложений Micro-Frontend.
Чтобы генерировать наше первое приложение Micro-Frontend, Navbar, мы будем следовать этим шагам:
cd .. mkdir single-spa-demo-nav cd single-spa-demo-nav npx create-single-spa
Затем мы будем следовать подсказкам CLI:
- Выберите «Приложение односпартамента/посылка»
- Выберите «Реагировать»
- Выберите «пряжу» или «NPM» (я выбрал «пряжа»)
- Введите имя организации, тот же, который вы использовали при создании приложения CORT CONFIG («Thakkin3» в моем случае)
- Введите название проекта (я использовал «однопроволочно-SPA-DEMO-NAV»)
Теперь, когда мы создали приложение Navbar, мы можем выполнить эти же шаги для создания наших двух страниц приложений. Но мы заменим каждое место, мы видим «однопроволочно-SPA-DEMO-NAV» с «однопроводом-демо-страницей-1» в первый раз, а затем с «однопроводом-демонстрационной страницей-2» второй раз через.
На данный момент мы сгенерировали все четыре приложения, которые нам нужны: одно контейнерное приложение и три приложения Micro-Frontend. Теперь пришло время подключить наши приложения вместе.
Как уже говорилось, одна из основных обязанностей приложения контейнера является координация, когда каждое приложение «активно» или нет. Другими словами, он обрабатывает, когда каждое приложение должно быть показано или скрыто.
Чтобы помочь приложению контейнера понять, когда каждое приложение должно быть показано, мы предоставляем ему, что называются «функциями активности». ” Каждое приложение имеет функцию действий, которая просто возвращает логическое значение, True или False, для того, будет ли приложение в настоящее время активно.
Внутри Однопроизводительный CORF-CONFIG каталог, в Деятельность-функции.js Файл, мы напишем следующие функции действий для наших трех приложений Micro Fressend.
export function prefix(location, ...prefixes) {
return prefixes.some(
prefix => location.href.indexOf(`${location.origin}/${prefix}`) !== -1
);
}
export function nav() {
// The nav is always active
return true;
}
export function page1(location) {
return prefix(location, 'page1');
}
export function page2(location) {
return prefix(location, 'page2');
}Далее нам нужно зарегистрировать наши три приложения Micro-Frontend с одним спа. Для этого мы используем ЗарегистрироватьсяВораспликация функция. Эта функция принимает минимум из трех аргументов: имя приложения, метод для загрузки приложения и функции действия, чтобы определить, когда приложение активно.
Внутри Однопроизводительный CORF-CONFIG каталог, в root-config.js Файл, мы добавим следующий код для регистрации наших приложений:
import { registerApplication, start } from "single-spa";
import * as isActive from "./activity-functions";
registerApplication(
"@thawkin3/single-spa-demo-nav",
() => System.import("@thawkin3/single-spa-demo-nav"),
isActive.nav
);
registerApplication(
"@thawkin3/single-spa-demo-page-1",
() => System.import("@thawkin3/single-spa-demo-page-1"),
isActive.page1
);
registerApplication(
"@thawkin3/single-spa-demo-page-2",
() => System.import("@thawkin3/single-spa-demo-page-2"),
isActive.page2
);
start();Теперь, когда мы настроили функции деятельности и зарегистрировали наши приложения, последний шаг, прежде чем мы сможем получить эту работу локально, это обновить локальную карту импорта внутри index.ejs файл в том же каталоге.
Мы добавим следующий код внутри голова Теги, чтобы указать, где каждое приложение можно найти при работе на месте:
<% if (isLocal) { %>
<% } %> Каждое приложение содержит свой собственный скрипт запуска, что означает, что каждое приложение будет работать на месте на своем собственном сервере разработки во время локального развития. Как видите, наше приложение Navbar находится в порту 9001, наша приложение Page 1 находится на порту 9002, и наша приложение Page 2 находится на порту 9003.
С этими тремя шагами позаботились о том, давайте попробуем наше приложение.
Чтобы заставить наше приложение работать на месте, мы можем выполнить следующие шаги:
- Открыть четыре вкладыки терминалов, один для каждого приложения
- Для корневой конфигурации в
Однопроизводительный CORF-CONFIGКаталог:Пряжа начать(работает по порту 9000 по умолчанию) - Для приложения навигации в
Односпа-Demo-NavКаталог:Пряжа начать --port 9001 - Для приложения Page 1, в
Однопроизводительная Demo-Page-1Каталог:Пряжа начать --port 9002 - Для приложения Page 2, в
Однопроизводитель-демо-страница-2Каталог:Пряжа начать --port 9003
Теперь мы ориентируемся в браузер к http://localhost: 9000 Чтобы просмотреть наше приложение.
Мы должны увидеть … какой-то текст! Супер захватывающий.
На нашей главной странице NAVBAR отображается, потому что приложение Navbar всегда активно.
Теперь давайте перейду на http://localhost: 9000/Page1. Как показано в нашей активности функции выше, мы указывали, что приложение Page 1 должно быть активным (показано), когда путь URL начинается с «Page1». Итак, это активирует приложение Page 1, и мы должны увидеть текст как для NAVBAR, так и для приложения Page 1.
Еще раз, давайте теперь перейду на http://localhost: 9000/стр .2. Как и ожидалось, это активирует приложение Page 2, поэтому мы должны увидеть текст на Navbar и App Page 2.
До сих пор наше приложение не очень интересно рассмотреть, но у нас есть работающая настройка Micro-Frontend, работающая на месте. Если вы не воспринимаете на своем месте прямо сейчас, вы должны быть!
Давайте сделаем некоторые незначительные улучшения нашим приложениям, чтобы они выглядели и ведут себя немного приятнее.
Указание крепежных контейнеров
Во-первых, если вы обновляете свою страницу снова и снова при просмотре приложения, вы можете заметить, что иногда приложения загружаются из строя, а приложение страницы появляется над приложением NAVBAR.
Это потому, что мы на самом деле не указали где каждое приложение должно быть установлено. Приложения просто загружены Systemjs , а затем в зависимости от того, что приложение заканчивает загрузку, самые быстрые, получено на страницу первым.
Мы можем исправить это, указав контейнер для крепления для каждого приложения, когда мы зарегистрируем их.
В нашем index.ejs Файл, который мы работали ранее, давайте добавим HTML для обслуживания основных контейнеров контента для страницы:
Тогда, в нашем root-config.js Файл, в котором мы зарегистрировали наши приложения, давайте предоставим четвертый аргумент для каждого вызова функции, который включает в себя элемент DOM, где мы хотели бы установить каждое приложение:
import { registerApplication, start } from "single-spa";
import * as isActive from "./activity-functions";
registerApplication(
"@thawkin3/single-spa-demo-nav",
() => System.import("@thawkin3/single-spa-demo-nav"),
isActive.nav,
{ domElement: document.getElementById('nav-container') }
);
registerApplication(
"@thawkin3/single-spa-demo-page-1",
() => System.import("@thawkin3/single-spa-demo-page-1"),
isActive.page1,
{ domElement: document.getElementById('page-1-container') }
);
registerApplication(
"@thawkin3/single-spa-demo-page-2",
() => System.import("@thawkin3/single-spa-demo-page-2"),
isActive.page2,
{ domElement: document.getElementById('page-2-container') }
);
start();Теперь приложения всегда будут установлены в конкретное и предсказуемое местоположение. Отлично!
Стайлинг приложение
Далее давайте немного стиль наш приложение. Простой черный текст на белом фоне не очень интересно смотреть.
В Однопроизводительный CORF-CONFIG каталог, в index.ejs Файл снова, мы можем добавить некоторые основные стили для всего приложения, вставив следующие CSS внизу голова ярлык:
Далее мы можем стиль нашего приложения Navbar, найдя Односпа-Demo-Nav каталог, создание root.component.css Файл и добавление следующих CSS:
.nav {
display: flex;
flex-direction: row;
padding: 20px;
background: #000;
color: #fff;
}
.link {
margin-right: 20px;
color: #fff;
text-decoration: none;
}
.link:hover,
.link:focus {
color: #1098f7;
}Затем мы можем обновить root.component.js Файл в том же каталоге для импорта файла CSS и применять эти классы и стили на наш HTML. Мы также изменим содержимое NAVBAR, чтобы фактически содержать две ссылки, чтобы мы могли перемещаться по приложению, щелкнув ссылки вместо ввода нового URL в адресной строке браузера.
import React from "react";
import "./root.component.css";
export default function Root() {
return (
);
}Мы будем следовать аналогичному процессу приложений Page 1 и Page 2. Мы создадим root.component.css Файл для каждого приложения в их соответствующих каталогах проекта и обновить root.component.js Файлы для обоих приложений тоже.
Для приложения Page 1 изменения выглядят так:
.container1 {
background: #1098f7;
color: white;
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
flex: 1;
font-size: 3rem;
}import React from "react";
import "./root.component.css";
export default function Root() {
return (
Page 1 App
);
}А для приложения Page 2 изменения выглядят так:
.container2 {
background: #9e4770;
color: white;
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
flex: 1;
font-size: 3rem;
}import React from "react";
import "./root.component.css";
export default function Root() {
return (
Page 2 App
);
}Добавление React Router
Последнее небольшое изменение, которое мы сделаем, это добавить React Router в наше приложение. Прямо сейчас две ссылки, которые мы разместили в Navbar, – это просто обычные якорные теги, поэтому навигация на странице на странице вызывает обновление страницы. Наше приложение будет намного гладким, если навигация обрабатывается на стороне клиента с React Router.
Чтобы использовать React Router, нам сначала нужно установить его. От терминала, в Односпа-Demo-Nav Каталог, мы устанавливаем React Router с помощью пряжи, введя пряжа Добавить React-Router-DOM Отказ (Или если вы используете NPM, вы можете ввести NPM Установить React-Router-DOM .)
Тогда в Односпа-Demo-Nav каталог в root.component.js Файл, мы заменим наши якорные теги с помощью React Router’s Ссылка Компоненты, как так:
import React from "react";
import { BrowserRouter, Link } from "react-router-dom";
import "./root.component.css";
export default function Root() {
return (
);
}Прохладный. Это выглядит и работает намного лучше!
На данный момент у нас есть все, что нам нужно, чтобы продолжить работу над приложением, работая на нем на месте. Но как мы получаем его где-то публично доступно?
Есть несколько возможных подходов, которые мы можем взять с использованием наших инструментов выбора, но основными задачами являются:
- Чтобы иметь где-то мы можем загрузить наши сборки артефактов, как CDN, а также
- Чтобы автоматизировать этот процесс загрузки артефактов каждый раз, когда мы объединяем новый код в основную ветку.
Для этой статьи мы собираемся использовать AWS S3 для хранения наших активов, и мы собираемся использовать TRAVIS CI для запуска задания сборки и задание загрузки в рамках конвейера непрерывного интеграции.
Давайте сначала получим ведро S3.
Настройка ведра AWS S3
Это должно пойти, не сказав, но вам понадобится учетная запись AWS, если вы следуете вдоль здесь.
Если мы являемся пользователем root на нашей учетной записи AWS, мы можем создать новый пользователь IAM, который имеет только программный доступ. Это означает, что мы получим идентификатор ключа доступа и ключ секретного доступа от AWS, когда мы создаем новый пользователь. Мы захочем хранить их в безопасном месте, поскольку нам понадобится позже.
Наконец, этот пользователь должен давать разрешения только для работы с S3, чтобы уровень доступа ограничен, если наши ключевые ключи попадают в неправильные руки.
У AWS есть несколько отличных ресурсов для Лучшие практики с ключами доступа и Управление ключами доступа для IAM пользователей Это было бы важно проверить, если вы незнакомы с тем, как это сделать.
Далее нам нужно создать ведро S3. S3 обозначает простую услугу хранения и по сути, – это место для загрузки и хранения файлов, размещенных на серверах Amazon. Ведро – это просто каталог.
Я назвал мою ведро «Односпасться в Spa-Demo», но вы можете назвать твоего, что вы хотели бы. Вы можете следовать гидам AWS для Как создать новое ведро для получения дополнительной информации.
Как только мы создали наше ведро, также важно убедиться, что ведро публичное и что CORS (общий ресурс перекрестного происхождения) включен для нашего ведра Так что мы можем получить доступ и использовать наши загруженные активы в нашем приложении.
В разрешениях для нашего ведра мы можем добавить следующие правила конфигурации CORS:
* GET
В консоли AWS он в конечном итоге выглядит так, как мы ударили сохранение:
Создание работы TRAVIS CI для загрузки артефактов в AWS S3
Теперь, когда у нас есть куда-то для загрузки файлов, давайте настроим автоматизированный процесс, который позаботится о загрузке новых связке JavaScript каждый раз, когда мы объединяем новый код в главную ветку для любого из наших REPOS.
Для этого мы собираемся использовать Трэвис СИ . Как упоминалось ранее, каждое приложение живет в своем собственном репо на Github, поэтому у нас есть четыре репос для работы GitHub. Мы можем Интеграция TRAVIS CI с каждым из наших REPOS и установить непрерывный интеграционные трубопроводы для каждого.
Чтобы настроить TRAVIS CI для любого данного проекта, мы создаем .travis.yml Файл в корневом каталоге проекта. Давайте создадим этот файл в Однопроизводительный CORF-CONFIG каталог и вставьте следующий код:
language: node_js
node_js:
- node
script:
- yarn build
- echo "Commit sha - $TRAVIS_COMMIT"
- mkdir -p dist/@thawkin3/root-config/$TRAVIS_COMMIT
- mv dist/*.* dist/@thawkin3/root-config/$TRAVIS_COMMIT/
deploy:
provider: s3
access_key_id: "$AWS_ACCESS_KEY_ID"
secret_access_key: "$AWS_SECRET_ACCESS_KEY"
bucket: "single-spa-demo"
region: "us-west-2"
cache-control: "max-age=31536000"
acl: "public_read"
local_dir: dist
skip_cleanup: true
on:
branch: masterЭта реализация в том, что я придумал после рассмотрения Travis CI Docs для AWS S3 Загружает и а Single-Spa Travis CI Пример Config Отказ
Поскольку мы не хотим, чтобы наши тайны AWS выставлены в нашем репо GitHub, мы можем хранить те, которые в качестве переменных окружающей среды. Вы можете разместить переменные среды и их секретные значения в веб-консоли TRAVIS CI для всего, что вы хотите сохранить частные, так что это где .travis.yml Файл получает эти значения от.
Теперь, когда мы совершаем и выдвинули новый код в главную ветку, задание TRAVIS CI запускается, что будет создавать пакет JavaScript для приложения, а затем загружать эти активы на S3. Чтобы проверить, мы можем проверить консоль AWS, чтобы увидеть наши недавно загруженные файлы:
Аккуратный! Все идет нормально. Теперь нам нужно реализовать ту же конфигурацию TRAVIS CI для наших трех других приложений Micro-Frontend, но именные имена каталогов в .travis.yml файл по мере необходимости. После последующих одинаковых шагов и слияние нашего кода, у нас теперь есть четыре каталогов, созданные в нашем ведре S3, по одному для каждого репо.
Давайте повторимся, что мы сделали до сих пор. У нас есть четыре приложения, все живущие в отдельных репос для GitHub. Каждое репо настроено с помощью TRAVIS CI для запуска задания, когда код объединяется в главную ветку, и этот рабочие характеристики загружают артефакты сборки в ведро S3.
Со всем тем, что в одном месте все еще отсутствует: как эти новые артефакты сборки ссылоятся в нашем контейнере? Другими словами, даже если мы подталкиваем новые пакеты JavaScript для наших микрофонов с каждым новым обновлением, новый код еще не используется в нашем приложении контейнера!
Если мы подумаем, как мы получили наше приложение, работающее на месте, мы использовали карту импорта. Эта карта импорта – это просто JSON, которая говорит о приложении контейнера, в котором можно найти каждый пакет JavaScript.
Но наша импортная карта из ранее была специально использована для проведения приложения локально. Теперь нам нужно создать карту импорта, которая будет использоваться в производственной среде.
Если мы посмотрим в Однопроизводительный CORF-CONFIG каталог, в index.ejs Файл, мы видим эту строку:
Открытие этого URL в браузере раскрывает карту импорта, которая выглядит так:
{
"imports": {
"react": "https://cdn.jsdelivr.net/npm/react@16.13.1/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@16.13.1/umd/react-dom.production.min.js",
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.5.3/lib/system/single-spa.min.js",
"@react-mf/root-config": "https://react.microfrontends.app/root-config/e129469347bb89b7ff74bcbebb53cc0bb4f5e27f/react-mf-root-config.js",
"@react-mf/navbar": "https://react.microfrontends.app/navbar/631442f229de2401a1e7c7835dc7a56f7db606ea/react-mf-navbar.js",
"@react-mf/styleguide": "https://react.microfrontends.app/styleguide/f965d7d74e99f032c27ba464e55051ae519b05dd/react-mf-styleguide.js",
"@react-mf/people": "https://react.microfrontends.app/people/dd205282fbd60b09bb3a937180291f56e300d9db/react-mf-people.js",
"@react-mf/api": "https://react.microfrontends.app/api/2966a1ca7799753466b7f4834ed6b4f2283123c5/react-mf-api.js",
"@react-mf/planets": "https://react.microfrontends.app/planets/5f7fc62b71baeb7a0724d4d214565faedffd8f61/react-mf-planets.js",
"@react-mf/things": "https://react.microfrontends.app/things/7f209a1ed9ac9690835c57a3a8eb59c17114bb1d/react-mf-things.js",
"rxjs": "https://cdn.jsdelivr.net/npm/@esm-bundle/rxjs@6.5.5/system/rxjs.min.js",
"rxjs/operators": "https://cdn.jsdelivr.net/npm/@esm-bundle/rxjs@6.5.5/system/rxjs-operators.min.js"
}
}Эта импортная карта была по умолчанию, приведенный в качестве примера, когда мы использовали CLI для создания нашего приложения для контейнера. То, что нам нужно сделать сейчас, замените этот пример импортированной карты на импортную карту, которая фактически называет пакеты, которые мы используем.
Таким образом, используя оригинальную карту импорта в качестве шаблона, мы можем создать новый файл под названием ImportMap.json Поместите это за пределами наших репо И добавьте JSON, что выглядит так:
{
"imports": {
"react": "https://cdn.jsdelivr.net/npm/react@16.13.0/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@16.13.0/umd/react-dom.production.min.js",
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.5.1/lib/system/single-spa.min.js",
"@thawkin3/root-config": "https://single-spa-demo.s3-us-west-2.amazonaws.com/%40thawkin3/root-config/179ba4f2ce4d517bf461bee986d1026c34967141/root-config.js",
"@thawkin3/single-spa-demo-nav": "https://single-spa-demo.s3-us-west-2.amazonaws.com/%40thawkin3/single-spa-demo-nav/f0e9d35392ea0da8385f6cd490d6c06577809f16/thawkin3-single-spa-demo-nav.js",
"@thawkin3/single-spa-demo-page-1": "https://single-spa-demo.s3-us-west-2.amazonaws.com/%40thawkin3/single-spa-demo-page-1/4fd417ee3faf575fcc29d17d874e52c15e6f0780/thawkin3-single-spa-demo-page-1.js",
"@thawkin3/single-spa-demo-page-2": "https://single-spa-demo.s3-us-west-2.amazonaws.com/%40thawkin3/single-spa-demo-page-2/8c58a825c1552aab823bcbd5bdd13faf2bd4f9dc/thawkin3-single-spa-demo-page-2.js"
}
}Вы отметиете, что первые три импорта предназначены для совместных зависимостей: React, React-Dom и One-Spa. Таким образом, у нас нет четырех копий реагирования в нашем приложении, вызывающих раздувание и более длительное время загрузки. Далее у нас есть импорт для каждого из наших четырех приложений. URL – это просто URL для каждого загруженного файла в S3 (называемый «объектом» в терминологии AWS).
Теперь, когда у нас есть этот файл создан, мы можем вручную загрузить его в наше ведро в S3 через консоль AWS.
Примечание : Это довольно важное и интересное предупреждение при использовании однопрочего SPA: карта импорта на самом деле не живет в любом месте исходного управления или в любом из REPOS. Таким образом, карта импорта может быть обновлена на лету, не требуя зарегистрированных изменений в репо. Мы вернемся к этой концепции немного.
Наконец, теперь мы можем ссылаться на этот новый файл в нашем index.ejs Файл вместо ссылки на оригинальную карту импорта.
Мы приближаемся к тому, чтобы иметь что-то и бежать в производстве! Мы собираемся принять эту демонстрацию на Heroku, поэтому, чтобы сделать это, нам нужно создать простой Node.js и Экспресс Сервер для обслуживания нашего файла.
Во-первых, в Однопроизводительный CORF-CONFIG Справочник, мы установим экспресс запуском пряжа добавить экспресс (или NPM Install Express ). Далее мы добавим файл под названием Server.js который содержит небольшое количество кода для запуска экспресс-сервера и обслуживание нашего главного index.html файл.
const express = require("express");
const path = require("path");
const PORT = process.env.PORT || 5000;
express()
.use(express.static(path.join(__dirname, "dist")))
.get("*", (req, res) => {
res.sendFile("index.html", { root: "dist" });
})
.listen(PORT, () => console.log(`Listening on ${PORT}`));Наконец, мы обновим сценарии NPM в нашем package.json Файл для дифференцирования между запуском сервера в режиме разработки и запуском сервера в режиме производства.
"scripts": {
"build": "webpack --mode=production",
"lint": "eslint src",
"prettier": "prettier --write './**'",
"start:dev": "webpack-dev-server --mode=development --port 9000 --env.isLocal=true",
"start": "node server.js",
"test": "jest"
}Теперь, когда у нас есть производственный сервер готов, давайте сделаем эту вещь, развернутую в Heroku! Для этого вам нужно будет Учетная запись Heroku создана , Heroku Cli установлен и войти в систему. Развертывание Heroku так просто, как 1-2-3:
- В
Однопроизводительный CORF-CONFIGКаталог:Heroku Создать Thakkin3-Single-Spa-Demo(Изменение этого последнего аргумента для уникального имени, которое будет использоваться для вашего приложения Heroku) Git Push Heroku MasterHeroku Open.
И с этим мы заканчиваемся в производстве. При запуске Heroku Open Команда, вы должны увидеть ваше приложение открытым в вашем браузере. Попробуйте навигацию между страницами, используя ссылки на NAV, чтобы увидеть различные приложения Micro-Frontend Apps и Messount.
На данный момент вы можете спрашивать себя: «Все, что эта работа для этого? Почему?” И ты был бы прав. Вроде, как бы, что-то вроде. Это много работы, и у нас нет много, чтобы показать на нем, по крайней мере, не визуально. Но мы заложили основу для всех улучшений приложений, которые мы хотели бы.
Стоимость установки для любого микросервиса или микрофона часто намного выше, чем стоимость установки для монолита; Это не до тех пор, пока вы начинаете пожинать награды.
Так что давайте начнем думать о будущих модификациях. Допустим, это сейчас пять или десять лет спустя, и ваше приложение выросло. Много. И, в то время была выпущена горячая новая структура, и вы умираете, чтобы переписать все свое приложение, используя эту новую структуру.
Работая с монолитным, это, скорее всего, будет долгим долгом, и может быть почти невозможным достичь. Но, с микропропиннами, вы можете поменять технологии одним куском приложения за раз, позволяя вам медленно и плавно переходить на новый технологический стек. Магия!
Или у вас может быть одна часть вашего приложения, которое часто меняется, а другая часть вашего приложения, которое редко касается. При этом обновления в волатильное приложение, не было бы неплохо, если бы вы могли просто оставить наследийный код в одиночку?
С монолитным, возможно, что изменения, которые вы делаете в одном месте вашего приложения, могут повлиять на другие разделы вашего приложения. Что, если вы изменили некоторые стилы, которые использовали несколько разделов монолита? Или что, если вы обновили зависимость, которая использовалась во многих разных местах?
С помощью подхода Micro-Frestend вы можете оставить эти заботы позади, рефакторинга и обновления одного приложения, где это необходимо, оставив наследственные приложения в одиночку.
Но как вы делаете такие обновления? Или обновления любого рода, правда?
Прямо сейчас у нас есть наша карта импорта производства в нашем index.ejs файл, Но это просто указывает на файл, который мы вручную загрузили в наше ведро S3. Если мы хотели выпустить некоторые новые изменения прямо сейчас, нам нужно будет толкать новый код для одного из микрофонов, получите новый артефакт сборки, а затем вручную обновить карту импорта со ссылкой на новый пакет JavaScript.
Есть ли способ, которым мы могли бы автоматизировать это? Да!
Допустим, мы хотим обновить нашу страницу 1 приложение для разных текстов. Чтобы автоматизировать развертывание этого изменения, мы можем обновить наш трубопровод CI, чтобы не только создать артефакт и загружать его в наше ведро S3, но также обновить карту импорта для ссылки на новый URL для нового URL-адреса для новейшего JavaScript.
Давайте начнем с обновления наших .travis.yml файл вроде:
language: node_js
node_js:
- node
env:
global:
# include $HOME/.local/bin for `aws`
- PATH=$HOME/.local/bin:$PATH
before_install:
- pyenv global 3.7.1
- pip install -U pip
- pip install awscli
script:
- yarn build
- echo "Commit sha - $TRAVIS_COMMIT"
- mkdir -p dist/@thawkin3/root-config/$TRAVIS_COMMIT
- mv dist/*.* dist/@thawkin3/root-config/$TRAVIS_COMMIT/
deploy:
provider: s3
access_key_id: "$AWS_ACCESS_KEY_ID"
secret_access_key: "$AWS_SECRET_ACCESS_KEY"
bucket: "single-spa-demo"
region: "us-west-2"
cache-control: "max-age=31536000"
acl: "public_read"
local_dir: dist
skip_cleanup: true
on:
branch: master
after_deploy:
- chmod +x after_deploy.sh
- "./after_deploy.sh"Основные изменения здесь добавляют переменную глобальной среды, устанавливая AWS CLI и добавление После_deploy . скрипт как часть трубопровода. Это ссылки на После_deploy.sh Файл, который нам нужно создать. Содержание будет:
echo "Downloading import map from S3" aws s3 cp s3://single-spa-demo/@thawkin3/importmap.json importmap.json echo "Updating import map to point to new version of @thawkin3/root-config" node update-importmap.mjs echo "Uploading new import map to S3" aws s3 cp importmap.json s3://single-spa-demo/@thawkin3/importmap.json --cache-control 'public, must-revalidate, max-age=0' --acl 'public-read' echo "Deployment successful"
Этот файл загружает существующую карту импорта из S3, изменяет его для ссылки на новый артефакт Build, а затем повторно загрузите обновленную карту импорта на S3. Чтобы обработать фактическое обновление содержимого файла импорта карты, мы используем пользовательский скрипт, который мы добавим в файл под названием Update-imoteMap.mjs.
// Note that this file requires node@13.2.0 or higher (or the --experimental-modules flag)
import fs from "fs";
import path from "path";
import https from "https";
const importMapFilePath = path.resolve(process.cwd(), "importmap.json");
const importMap = JSON.parse(fs.readFileSync(importMapFilePath));
const url = `https://single-spa-demo.s3-us-west-2.amazonaws.com/%40thawkin3/root-config/${process.env.TRAVIS_COMMIT}/root-config.js`;
https
.get(url, res => {
// HTTP redirects (301, 302, etc) not currently supported, but could be added
if (res.statusCode >= 200 && res.statusCode < 300) {
if (
res.headers["content-type"] &&
res.headers["content-type"].toLowerCase().trim() ===
"application/javascript"
) {
const moduleName = `@thawkin3/root-config`;
importMap.imports[moduleName] = url;
fs.writeFileSync(importMapFilePath, JSON.stringify(importMap, null, 2));
console.log(
`Updated import map for module ${moduleName}. New url is ${url}.`
);
} else {
urlNotDownloadable(
url,
Error(`Content-Type response header must be application/javascript`)
);
}
} else {
urlNotDownloadable(
url,
Error(`HTTP response status was ${res.statusCode}`)
);
}
})
.on("error", err => {
urlNotDownloadable(url, err);
});
function urlNotDownloadable(url, err) {
throw Error(
`Refusing to update import map - could not download javascript file at url ${url}. Error was '${err.message}'`
);
}Обратите внимание, что нам необходимо сделать эти изменения для этих трех файлов во всех наших репос GitHub, чтобы каждый мог обновить карту импорта после создания нового артефакта сборки.
Содержимое файла будет почти идентичным для каждого репо, но нам нужно будет изменить имена приложений или путей URL к соответствующим значениям для каждого.
Боковая заметка на карте импорта
Ранее я упомянул, что файл импорта карты, который мы вручную загружены на S3, на самом деле не живут нигде в любом из наших REPOS Github или в любом из наших зарегистрированных кода. Если вы похожи на меня, это, вероятно, кажется действительно странным! Не должно все быть в контроле источника?
Причина, по которой это не в контроле источника, так что наш трубопровод CI может обрабатывать обновление карты импорта с каждым новым выпуском приложения Micro-Frontend.
Если карта импорта была в контроле источника, создавая обновление до одного приложения Micro-Frontend, потребует изменений в двух репо, приложении Micro-Frontend, где выполнено изменение, и Ref Config Repo, когда карта импорта будет проверена в Отказ Такая настройка будет недействительна одним из основных преимуществ архитектуры Micro-Frestend, что заключается в том, что каждое приложение может быть развернуто полностью независимым от других приложений.
Для достижения некоторого уровня контроля источника на карте импорта мы всегда можем использовать функцию версий S3 для нашего ведра.
С этими модификациями на наших трубопроводов CI на место, пришло время для окончательного момента истины: можем ли мы обновить одно из наших приложений Micro-Frontend, развертывая его самостоятельно, а затем увидеть, что эти изменения вступают в силу в производстве без необходимости прикоснуться к ним Другие приложения?
В Однопроизводительная Demo-Page-1 каталог, в root.component.js Файл, давайте изменим текст из «App Page 1» на «Page 1 App – обновлено!» Далее давайте покончим это изменение и толкните и сливайте его мастеру.
Это забивает трубопровод Travis CI, чтобы построить App Page 1 App Artifact, а затем обновить карту импорта, чтобы ссылаться на этот новый URL-адрес файла.
Если мы отправимся в браузер к https://thawkin3-single-spa-demo.herokuapp.com/page1 Теперь мы посмотрим … Brum Roll, пожалуйста … наше обновленное приложение!
Я сказал это раньше, и я скажу это снова: Micro-Frestendes – это будущее веб-разработки Frontend.
Преимущества являются массивными, включая независимые развертывания, независимые области собственности, более быстрые постройки и время тестирования и возможность смешивать и сопоставить различные рамки, если это необходимо.
Есть некоторые недостатки, такие как первоначальная стоимость установления и сложность поддержания распределенной архитектуры, но я настоятельно верю, что выгоды перевешивают затраты.
Однопрокат делает архитектуру Micro-Frontend легко. Теперь ты тоже можешь расстаться на монолит!
Оригинал: “https://www.freecodecamp.org/news/developing-and-deploying-micro-frontends-with-single-spa/”