Раскрытие тайны микрофронтендов. Фреймворк микрофронтенда, основанный на single-spa.

Архитектура

image.png
  исходный адрес
  Микро интерфейс опробовал коллега в компании вскоре после того, как я начал работать, и мне посчастливилось в нем поучаствовать. До того, как появилось понятие микрофронтенды, появились и стали популярными микросервисы, а микрофронтенды генерировались путем заимствования архитектуры микросервисов, они очень похожи, и мы можем их сравнить и понять.

Микросервисы микро интерфейс
Микросервис состоит из набора интерфейсов, а адрес интерфейса обычно представляет собой URL-адрес. Когда микросервис получает запрос от интерфейса, он выполняет маршрутизацию для поиска соответствующей логики и вывода содержимого ответа.

Серверная микрослужба будет иметь шлюз, который получает все запросы клиентского интерфейса как одну запись и направляет их к соответствующей службе в соответствии с взаимосвязью соответствия между URL-адресом интерфейса и службой.
Микро-интерфейс состоит из набора страниц, а адрес страницы также является URL-адресом. Когда микроинтерфейс получает запрос URL-адреса страницы, он направляет его для поиска соответствующего компонента и отображения содержимого страницы.

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

                    Таблица I
В сети также много дискуссий о микро-фронтенде. Я думал, что микро-фронтенд очень сложная штука. Однако после того, как я лично в нем поучаствовал, я обнаружил, что микро-фронтенд не сложен для понимания. проведет вас шаг за шагом.
   Схем реализации микрофронтендов много, сегодня мы используем самые популярные.single-spa Путь. Если вы изучите его, вы можете попытаться реорганизовать приложение вашей компании в виде микро-фронтенда.

Предыстория нашего микроинтерфейса

   Прежде всего, нам нужно знать, что такое микро-фронтенд, Если я говорю это в соответствии с концепцией здесь, я считаю, что все более абстрактны. Я расскажу о предыстории наших микрофронтендов здесь, и все узнают, какие проблемы могут решить микрофронтенды, и тогда поймут, что такое микрофронтенды.
В моей группе много предприятий 2B, а позже стратегия компании изменилась, и появилось много новых направлений бизнеса. Каждое направление бизнеса имеет свои собственные функции работы. Чтобы удовлетворить операционные потребности этих новых направлений бизнеса, все, что нам нужно сделать это:

  1. Добавить функцию переключения бизнес-линий на исходный фон операции
  2. Перенос операционных функций, разбросанных по другим платформам
  3. Разрабатывайте индивидуальные функции для каждого направления бизнеса и отображайте их в соответствии с направлением бизнеса.
  4. Для функций, настроенных по бизнес-направлениям, они будут стараться отвечать за каждое бизнес-направление, что требует разработки каждого бизнес-направления с использованием единого стека технологий.

   Окончательный рендеринг выглядит так, как показано ниже.

image.png
                    фигура 1

  По конструкции традиционной схемы так и есть, но это вызовет следующие проблемы:

  1. Исходный фон операции необходимо реконструировать.Основные моменты реконструкции - аутентификация и коммутация бизнес-линии.Конечно, некоторые внутренние интерфейсы также должны быть обработаны.
  2. Затраты на миграцию для других функций платформы немного высоки, поскольку используются разные технологические стеки.
  3. С ростом операционных требований платформа будет становиться все больше и больше, что приведет к росту затрат на обслуживание, недостаточной гибкости итераций, а совместная работа нескольких человек будет вызывать различные конфликты.
  4. Ошибка в модуле может привести к сбою всей системы.

Преимущества использования микрофронтендов

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

image.png
                    фигура 2
   Так как же это достигается? Далее мы используем Vue+single-spa для реализации системы микро-интерфейса, и вы можете понять принцип микро-интерфейса.

Основы микро-фронтендов

Для микроинтерфейсной системы требуется основной модуль и несколько подмодулей.Основной модуль содержит входной файл всего проекта.Подпроекты должны быть зарегистрированы и отображены в соответствии с сопоставлением маршрутов.Далее, домашняя страница, логин, меню, необходимо предоставить аутентификацию и услуги, коммутатор и т. д. Подпроекты не должны иметь файлы HTML, а должны только выводить файлы ресурсов, включая js/css/img/fonts и так далее.
Когда пользователь входит в систему микроинтерфейса, первым делом запускается загрузчик (упомянутый в таблице 1 выше), и загрузчик регистрирует каждый модуль.После успешной регистрации модуля, когда пользователь входит в этот модуль, micro front-end loader Модуль будет отрендерен, а затем будет выполнена функция хука:

  • Жизненный цикл начальной загрузки будет выполняться только один раз при его монтировании.
  • жизненный цикл монтирования, выполняемый при монтировании загрузчика.
  • жизненный цикл размонтирования, выполняемый при выгрузке субмодуля.

image.png

                   изображение 3

single-spa+Vue+Element реализует интерфейсную микросистему

  В соответствии с вышеупомянутым принципом микроинтерфейса и блок-схемой я покажу вам создание основного проекта и подпроектов с помощью single-spa+Vue+Element, а затем завершите настоящее приложение микроинтерфейса. Для того, чтобы всем было понятно, в данном объяснении не будет добавлена ​​функция переключения бизнес-направлений.Эта функция важна, но не трудоемка в реализации.Студенты могут добавить эту логику самостоятельно после построения микро-фронтенда.

основной проект

Входной файл main.js

Наш основной проект использует технологический стек Vue+Element. main.js такой же, как и традиционный проект Vue для завершения инициализации объекта Vue. Самый простой входной файл main.js реализован ниже. Я думаю, что все знакомы с ним. . . .

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import Router from 'vue-router';
import routerMap from './router/index';
import App from './App';
import util from '@/common/js/util';
Vue.use(ElementUI);
Vue.use(Router);

// 绑定路由
const router = new Router(routerMap);

router.beforeEach((to, from, next) => {
    if (to.fullPath === '/login' || from.fullPath === '/login') {
        next();
    } else {
        // 判断是否登录
        if (!util.login()) {
            login(); // 登录
        } else {
            next();
        }
    }
});

new Vue({
    router,
    render: h => h(App)
}).$mount('#app');

Затем вам нужно импортировать конфигурацию субмодуля в main.js, который мы будем использовать, когда загрузчик регистрирует субмодуль.Ссылка на файл конфигурации выглядит следующим образом:

export default {
    test: {
        id: 1,
        parent: {
            id: 1,
            name: 'test管理'
        },
        name: 'test模块',
        path: 'http://xxx.com/app.js',
        router: '/test'
    },
    demo: {
        id: 2,
        parent: {
            id: 1,
            name: 'demo管理'
        },
        name: 'demo模块',
        path: 'http://xxx.com/app.js',
        router: '/demo'
    }
};

Затем импортируйте его и сохраните, добавьте в main.js:

import appList from './appList'
util.setCache('appList', appList);

конфигурация маршрутизации

Здесь следует отметить конфигурацию маршрутизации.Основной проект обеспечивает общую логику и связанные страницы, такие как домашняя страница, меню, логин, 404 и т. д. Для меню мы используем компонент NavMenu Elemnet, а логику и страницу (страницу портала) загрузчика. Таким образом, маршрут должен быть таким:

import Home from '@/views/Home';
import Portal from '@/views/Portal'; // 加载器
import Login from '@/views/Login';
import NotFound from '@/views/404';
export default {
		routes: [
  			{
            path: '/',
          	redirect: '/portal',
            component: Home,
            children: [
                {
                    name: 'Portal',
                    path: `/portal*`,    
                    component: Portal, // 加载模块
                }
            ]
        },
        {
            path: '/login',
            component: Login,
            meta: {
                label: '登录',
                hidden: true
            }
        },
        {
            path: '/404',
            component: NotFound,
            meta: {
                label: '404',
                hidden: true
            }
        },
        {
            path: '*',
            redirect: '/404',
            meta: {
                hidden: true
            }
        }
    ]
}

Страница портала загрузчика

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

<template>
    <div id="MICRO-APP"></div>
</template>
<script>
/* eslint-disable */
import util from '@/common/js/util';
import { registerApplication, start, getAppNames, getAppStatus, unloadApplication } from 'single-spa';

export default {
    data() {
        return {};
    },
    methods: {
        registry(key, app) {
            // 去重
            if (getAppNames().includes(key)) {
                return;
            }
            // registerApplication 用于注册我们的子项目,第一个参数为项目名称(唯一即可),第二个参数为项目地址,第三个参数为匹配的路由,第四参数为初始化传值。
            registerApplication(
                key,
                () => {
                    const render = () => {
                        // 渲染
                        return window.System.import(app.path).then(res => {
                            if (res) {
                                return res;
                            } else {
                                return render();
                            }
                        });
                    };
                    return render();
                },
                location => {
                    if (location.pathname.indexOf(app.router) !== -1) {
                        return true;
                    } else {
                        return false;
                    }
                }
            );
        },
        // 注册模块
        async registerApp() {
            const appList = util.getCache('appList');
            for (const key in appList) {
                if (appList.hasOwnProperty(key)) {
                    const app = appList[key];
                    this.registry(key, app);
                }
            }
        }
    },
    mounted() {
        start();   //  启动项目
        this.registerApp();// 注册模块
    }
};
</script>
<style lang="less" scoped>
#MICRO-APP {
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 10;
}
</style>

HTML-часть страницы   portal имеет только один корневой элемент с идентификатором MICRO-APP, который служит контейнером подпроекта, и мы настроим его в подмодуле.

Жизненный цикл

  Прежде чем объяснять registerApplication, мы сначала дадим введение в жизненный цикл зарегистрированного субмодуля, который поможет вам глубже понять принцип работы загрузчика и процесс регистрации. должны знать о том,Жизненный цикл, который я сказал, относится к жизненному циклу процесса регистрации подмодулей, а не к жизненному циклу этой страницы.
Зарегистрированный субмодуль пройдет через процесс загрузки (загрузки), инициализации (инициализации), монтирования (монтирования), размонтирования (размонтирования) и выгрузки (удаления). single-spa предоставляет крючки для этих процессов через «жизненный цикл». Эти функции крючка включают в себя:

  • bootstrap: эта функция жизненного цикла выполняется один раз перед первым монтированием подмодуля.
  • mount: в процессе регистрации подмодуля, когда activityFunction (третий параметр registerApplication) возвращает значение true, а подмодуль находится в размонтированном состоянии, будет вызвана функция жизненного цикла монтирования. При вызове функция будет определять текущий активированный маршрут на основе URL-адреса, создавать элементы DOM, прослушивать события DOM и т. д., чтобы представить отображаемый контент пользователю. После монтажа любой следующийИзменения в дочерних маршрутах(Такие какhashchangeилиpopstateи т. д.) больше не сработаетmount, каждый модуль должен обрабатывать его самостоятельно.
  • размонтировать: всякий раз, когда функция activityFunction приложения возвращает значение false, но приложение смонтировано, будет вызываться функция жизненного цикла размонтирования. Когда вызывается функция размонтирования, она очищает элементы DOM, прослушиватели событий, память, глобальные переменные и подписки на сообщения, которые были созданы при монтировании приложения.

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

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

метод регистрации

Этот метод определяется следующим образом:

singleSpa.registerApplication(
  app.key,
  application(app.path), 
  activityFunction(app.router),   
  { access_token: 'asnjknfjkds' }
);
function loadingFunction(path) {
  return import(path);
}
function activityFunction(location,router) {
  return location.pathname.indexOf(router) !== -1;
}

Объяснение параметра:

  • Первый параметр — это ключевое значение, которое должно быть уникальным.
  • Второй параметр — это функция обратного вызова, которая должна быть функцией (или методом «асинхронной функции»), возвращающей обещание. Эта функция не принимает аргументов и вызывается при первой загрузке подмодуля. Возвращенное обещание должно разрешаться в подмодуль, который может быть разрешен. Обычный метод реализации заключается в использовании импорта для загрузки: () => import('/path/to/application.js'), для независимого развертывания каждого приложения, импорт здесьSystemJS
  • Третий параметр также является функцией, возвращающей логическое значение.window.locationбудет вызываться как первый параметр.Когда функция возвращает истинное значение, приложение будет активировано.Обычно функция Activity будет активирована в соответствии сwindow.locationПуть после / определяет, нужно ли активировать приложение. После активации, если субмодуль не смонтирован, выполняется жизненный цикл монтирования.
  • Четвертый параметр — это настраиваемый параметр, и затем мы можем получить этот параметр через props**.**customProps в каждой функции жизненного цикла. Этот параметр может быть полезен, например, в следующих сценариях:
    • Каждое приложение имеет общий параметр, например: access_token
    • Выдать информацию об инициализации, такую ​​как цели рендеринга
    • Передайте ссылку на шину событий (eventBus) для облегчения связи между приложениями.

резюме

   Вышеприведенное объяснение основного проекта. Принцип все еще немного сложен, но объем кода для реализации невелик. Резюме:

  • mian.js — это входной файл основного проекта, который инициализирует проект и обрабатывает логику входа в систему, а также представляет файл конфигурации подмодуля.
  • конфигурация маршрутизации
  • Загрузка страницы портала для выполнения регистрации регистрации приложения, жизненный цикл немного сложен, но это не влияет на использование, если вы его не понимаете

подпроект

   Подпроекты в принципе могут использовать любой стек технологий.Здесь я беру Vue в качестве примера, чтобы реализовать с вами подмодуль.

single-spa-vue

После завершения основного проекта реализация подпроекта очень проста.Одна вещь, в основном используемая здесь, — это Single-spa-vue, SingLesPavue — это метод Single-Spa в сочетании с Vue, мы используем его для реализации жизненного цикла подмодуля. логика. Его первый параметр — Vue, второй параметр appOptions — это конфигурация VUE, которую мы обычно вводили.

Запись подпроекта mian.js

import Vue from 'vue';
import Router from 'vue-router';
import App from './App';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import routerMap from './router';
import store from './store';
import singleSpaVue from 'single-spa-vue';

Vue.use(ElementUI);
Vue.use(Router);

const router = new Router(routerMap);
const vueLifecycles = singleSpaVue({
    Vue,
    appOptions: {
        router,
        store,
        render: h => h(App),
        el:'#MICRO-APP'     // Portal页面中的子模块容器,子模块会被插入到该元素中
    }
});

export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;


Если вы хотите что-то сделать после функции жизненного цикла, вы можете сделать это ниже.

const vueLifecycles = singleSpaVue({...})
export const mount = props => vueLifecycles.mount(props).then(instance => {
  // do what you want with the Vue instance
  ...
})

конфигурация маршрутизации

import List from '../views/List.vue';
export default {
    mode: 'history',
    base: '/portal',
    routes: [
        {
            path: '/demo',
            redirect: '/demo/list',
            component: List
        },
        {
            name: 'List',
            path: '/demo/list',
            component: List
        }
    ]
};

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

резюме

Вышеизложенное касается объяснения подпроектов.

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

ресурс

  • Git-адрес исходного кода этого проекта:
    Основной проект:GitHub.com/will-fly/m...
    Демонстрация подпроекта:GitHub.com/will-fly/m...
    Последующие действия будут постепенно улучшаться, оптимизировать производительность проекта и добавлять ответные подпроекты, приветствовать звездное общение.

  • Быстро создавайте строительные леса для подпроектов:
    rv-cli
    инструкции
    npm i rv-cli -g
    rv create

Ссылаться на

qiankun.umijs.org/zh/
Специальности.Meituan.com/2018/09/06/…
Арири.Специи/архив/EA5…
nuggets.capable/post/684490…
nuggets.capable/post/684490…
nuggets.capable/post/684490…