Создание микро-фронтендов с использованием Angular Elements: руководство для начинающих

Автор оригинала: Swathi Prasad
  • Перевод
  • Tutorial

За последние десять лет фронтенд-разработка значительно усложнилась: от чистого HTML/CSS до таких тем, как высокая интерактивность, доступность, тестируемость и безопасность. Чтобы удовлетворить эти потребности, большинство команд разработчиков делятся на бекенд и фронтенд команды.



В дополнение к этому функциональность приложения стабильно растет, и в определенный момент становится нецелесообразным объединять несколько команд на одной кодовой базе.
Модный термин «Микро-фронтенды» стал обозначать подход к разделению растущего фронтенд-кода на простые в обслуживании части. Фронтенд делится на несколько функций или частей, которые релизятся и деплоятся независимыми командами, что повышает тестируемость, переиспользуемость и дает возможность выбирать разные технологии для каждого микро-интерфейса.


Здесь я остановлюсь и без дальнейших прелюдий, давайте создадим пример микро-фронтенда с использованием Angular elements.


Создание микро-фронтендов


В этой статье мы создадим пример системы бронирования путешествий. Давайте развернем два Angular-проекта, используя CLI: travel-booking и flight-booking.


Нам потребуется несколько зависимостей для билда и запуска кастомных элементов Angular. Установите следующие зависимости внутри flight-booking.


ng add @angular/elements
ng add ngx-build-plus

Эти зависимости также могут быть установлены через NPM. @angular/elements обеспечивает поддержку Angular элементов. ngx-build-plus – это расширение Angular CLI для сборки проектов.


Примечание: вам может потребоваться обновить версию модуля document-register-element до 1.8.1 в /flight-booking/package.json, как описано в данном issue.

Также установим модуль http-server в проекте flight-booking.


npm i -g http-server --save

Создайте booking компонент в flight-booking/src/app/. Изменим компонент следующим образом:
flight-booking/src/app/booking/booking.component.html


<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<a href="javascript:alert('Welcome to Flight Booking App!!');" style="font-size:25px;">{{ title }}</a>
</div>

flight-booking/src/app/booking/booking.component.ts


import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-flight-booking',
templateUrl: './booking.component.html',
styleUrls: ['./booking.component.scss']
})
export class BookingComponent implements OnInit {

title = 'Flight Booking App';

constructor() { }

ngOnInit() {
}

Давайте определим booking компонент как кастомный элемент в flight-booking/src/app/app.module.ts.


import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { createCustomElement } from '@angular/elements';
import { BookingComponent } from './booking/booking.component';
@NgModule({
  declarations: [
    AppComponent,
    BookingComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [],
  entryComponents: [
    BookingComponent
  ]
})
export class AppModule {
  constructor(private injector: Injector) {
  }  ngDoBootstrap() {
    const myCustomElement = createCustomElement(BookingComponent, { injector: this.injector });
    customElements.define('app-flight-booking', myCustomElement);
  }
}

Чтобы сбилдить проект в один JS-файл, нужно указать angular использовать модуль ngx-build-plus. Измените flight-booking/angular.json в трех местах следующим образом:


"architect": { 
"build": {   "builder": "ngx-build-plus:build",  ....
"serve": { 
"builder": "ngx-build-plus:dev-server",    ... 
"test": {   
"builder": "ngx-build-plus:karma",

Запуск проекта


Выполните следующую команду, чтобы собрать проект в один файл:


ng build --prod --output-hashing none --single-bundle true

–output-hashing (none) позволит избежать хэширования имен файлов.
–single-bundle (true) объединит все скомпилированные файлы в один JS-файл.
Запустите сервер.


http-server ./dist/flight-booking -p 8081

Аналогичным образом создайте еще один кастомный элемент train-booking и запустите сервер с портом 8082.


http-server ./dist/train-booking -p 8082

Обертка кастомного элемента


Давайте подключим кастомные элементы flight-booking и train-booking в приложение бронирования. Измените /travel-booking/index.html следующим образом.


<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>TravelBooking</title>
  <base href="/">  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
  <div style="margin-bottom: 10px;" id="flight-booking-container"><app-flight-booking></app-flight-booking></div>  <div id="train-booking-container"><app-train-booking></app-train-booking></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.9.1/zone.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.2.10/custom-elements-es5-adapter.js"></script>
  <script type="text/javascript" src="http://localhost:8081/main.js"></script>
  <script type="text/javascript" src="http://localhost:8082/main.js"></script>
</body>
</html>

Angular-у требуется zone.js, а custom-elements-es5-adapter.js обеспечивает поддержку кастомных элементов в браузере. Мы также подключили main.js из наших кастомных элементов.
Измените travel-booking/angular.json, чтобы переопределить порт сервера по умолчанию.


"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "travel-booking:build",
"port": 8080
}


Запуск основного приложения


Запустите приложение, используя ng serve. Финальное приложение будет выглядеть как-то так:


Итого


На простых примерах статья демонстрирует, как можно построить микро-фронтенд архитектуру, используя элементы Angular.

Реклама
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее

Комментарии 1

    +1

    Один минус такого решения: каждый такой модуль тянет с собой себе весь Angular, а это около 300kb кода.

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое