предисловие
Потребовалось больше недели, чтобы, наконец, вытащить маленьких Наггетсов.
Сначала я просто хотел использоватьqiankun
+vue
Структура основана на掘金
Возьмем простой примерdemo
, но не рассчитывал вдаваться в подробности карты разреза (обсессивно-компульсивное расстройство было диагностировано правильно).
На самом деле, у меня есть более глубокое понимание некоторых плюсов и минусов архитектуры микрофронтенда и опыта разработки, так что это неплохо.
Я надеюсь, что этот обмен может принести некоторые практические чувства и осознание осуществимости тем, кто хочет попробовать архитектуру микроинтерфейса, но все еще смотрит.
По крайней мере, вы можете научиться использовать его в этом практическом проекте.qiankun
+Vue
Заполните все петли для развертывания в развертывании.
-
"
生产环境
":"Самородки (MicroApps): www.channing-bbs.club" -
"
GitHub
":"портал"
"Why"
Говорите о «почему» двумя способами:
- Зачем использовать архитектуру микроинтерфейса?
- Зачем использовать qiankun+Vue для этого практического проекта?
Зачем использовать архитектуру микроинтерфейса
К этому моменту, возможно, вы более-менее узнали о преимуществах архитектуры микрофронтенда из многих качественных статей, поэтому я не буду повторять мандарин потери портфеля, в основном из личного опыта и некоторых ощущений. архитектура.
"Деконструкция приложений Boulder"
В прошлом году я взял на себя систему среднего и фонового управления внутренней информацией компании, и эта система была разработана год назад, на ней почти десять модулей подприложений, и в написании участвовало несколько разных людей, затем时间跨度长
➕人员配置复杂
Что может пойти не так?
-
项目工程结构复杂混乱
Стиль кода у всех фееричный и красочный, а уровень тоже неравномерный.Чужой код, который они не осмеливаются связывать друг с другом. Это привело к множеству забавных проблем, например, я видел два пакета инстанцирования axios, и они расположены в разных местах, библиотека компонентов, которая изначально была загружена по требованию, а потом я не знаю, какой милый да импортировал его полностью, функция исподтишка вводит исполнение в скрытом месте... -
library版本落后
Технологии в области внешнего интерфейса быстро меняются, но из-за большого временного промежутка и сложности проекта вы не можете гарантировать, что каждое обновление определенного пакета обратно совместимо, и это обновление не повлияет на каждый зависимый пакет. Я попал в ловушку такого рода проблемы.В то время, поскольку определенный пакет не мог использоваться другой старой версией пакета после обновления, некоторые странные ошибки появлялись одна за другой.Когда информация об ошибке относительно грубая, она действительно трудно найти эту проблему.где источник. Некоторые люди говорят, что если я не обновлю его, все закончится? Это правда, но что, если пакет нужно обновить, чтобы исправить собственную ошибку. -
扩展成本高
Поскольку весь код выполняется в одной среде, необходимо быть очень осторожным при расширении новых функциональных модулей.Во время разработки необходимо убедиться, что эта функция не повлияет на нормальное использование других существующих функций, и следить за тем, чтобы этого не происходило. Эта ситуация также увеличивает процесс тестирования и сложность. Кроме того, каждое небольшое изменение требует переупаковки всего проекта и повторного развертывания его в сети и т. д. Расширение функциональности сложного монолитного приложения — головная боль.
Может быть, повезло, что вы тоже соприкоснулись со мной с "дерьмовым кодом горы". Каждый раз, когда вы разрабатываете новую фичу, вы боитесь. Может быть, однажды это будет последняя гора, которая сокрушит программистов.
"Независимость от стека технологий"
Мне очень нравится то, что сказал Лу Синь:
❝"На самом деле, если все стеки веб-технологий могут быть унифицированы, а все обновления библиотек могут быть обратно совместимыми, нам действительно не нужны микроинтерфейсы."—— Лу Синь
❞
"Это微前端架构
Самая главная ценность"
Если каждый функциональный модуль может быть независимым от стека технологий, при разработке новых модулей мы можем использовать наиболее популярный стек технологий, как нам нравится, и нам больше не нужно учитывать ограничения, связанные с использованием сложных библиотек с низкой производительностью.
Например, Vue3 находится в самом разгаре (когда я пишу здесь, вы только что незаметно выпустили 3.0), волна захватывающих API не позволяет не радоваться. Однако, ограниченный оковами существующих проектов, вы не можете по-настоящему смело рефакторить весь проект, что очень расстраивает, не так ли?
С точки зрения босса, найм ограничен общим технологическим стеком компании (в случае супер-большой коровы). Доля талантов составляет пять или пять, то есть почти половина выбираемых талантов.
(Хотя ваш React на самом деле 6, наш существующий бизнес нуждается в талантах Vue, чтобы перемещать кирпичи на высокой скорости)
Конечно, если вы не очень разбираетесь в понятии микро-фронтенда, то можете порекомендовать с расслабленным настроем ознакомиться с этими статьями:
- Основная ценность микрофронтенда
- Вероятно, самое полное решение для микроинтерфейса, которое вы когда-либо видели.
- Micro Frontends
- Micro Frontends from martinfowler.com
"Зачем использовать Vue+qiankun для этого проекта"
На самом деле, первое, что нужно еще раз подчеркнуть основную ценность микро-интерфейсов, это技术栈无关
, а это значит, что в этом проекте можно использовать React или Vue или даже Angular, не важно, вы можете использовать любой фреймворк для замены одного из микроприложений или расширения микроприложения.
использоватьVue
Прямая причина для выполнения этого проекта в том, что я лучше знаком с Vue.Я могу легко решить узкое место в попытке новой архитектуры или использовать какие-то хакерские методы, чтобы обойти его.Даже если я ступлю на яму, я есть уверенность Некоторые.
Другая причина в том, чтоqiankun
На официальном сайте не приводится пример использования Vue, что может кого-то остановить. Так что я планирую использоватьVue
Сделайте практичный проект с открытым исходным кодом, чтобы больше людей, которые хотят использовать qiankun во Vue, могли последовать примеру инициализации и использования API во Vue.
затем используйтеqiankun
Причина в структуре, которую я считаю очень хорошей после сравнения некоторых решений по горизонтали:
- Простой доступ и легкая реконструкция существующих приложений
- Содержит почти все основные возможности, необходимые для создания системы микроинтерфейса (изоляция css, песочница js, предварительная загрузка, взаимодействие приложений).
- Производство доступно, обладает определенной надежностью и выдержало испытание онлайн-систем.
"ShowCases"
титульная страница
точка кипения
тема
буклет
Деятельность
Функция аутентификации при входе в данный проект не задействована, конечно, не потому, что ее сложно реализовать под архитектуру микро-фронтенда, основная причина в том, что с одной стороны信息安全
Учтите, что данные в этом проекте поступают из интерфейса самого Nuggets, если задействована пользовательская информация, требуется много усилий для поддержания безопасности пользовательской информации, с другой стороны, сложность этих функций практически вся На уровне обработки бизнес-логики, вqiankun
Каждое приложение может совместно использовать и использовать одни и те жеWebStorage
а такжеCookie
получить доступtoken
, поэтому сложность реализации, связанная с аутентификацией входа, заключается вовсе не в том, использовать ли архитектуру микро-фронтенда, а в сложности собственной бизнес-логики.
"How"
стек технологий
"развивать"
-
qiankun
Решения для микроинтерфейса -
Vue
Сегмент для всей семьи создает главную страницу -
AntDesign Vue
Личная библиотека любимых компонентов -
Koa
Использовался как простой BFF, я просто хотел запустить mock на Node для симуляции данных, а потом просто ставлю запрос на интерфейс строки Nuggets, что удобно для централизованной обработки и фильтрации данных интерфейса (таких как наггетсы в будущем). Интерфейс сильно изменен, и мне не нужно проходить код во фронтенд проекте один за другим, мне просто нужно обработать данные в первоначальный вид в BFF) -
channing-cli
(Это не имеет значения) инструмент командной строки для создания каркасов, разработанный мной для быстрого построения архитектуры микроинтерфейса.
"развертывать"
-
Nginx
Развертывание интерфейсных приложений -
pm2
Разверните службу узла -
腾讯云
1M пропускная способность одно ядро 2G нищая версия удаленный сервер CentOS7.5
Общая структура
"* Основная реализация"
Реализация ядра в основном делится на четыре пункта:
- Инициализация основного приложения
- Инициализация микроприложения
- запросить прокси
- связь между приложениями
"Инициализация основного приложения"
qiankun
просто нужно主应用
Средняя установка, микроприложения не требуются
"Установить в основном приложенииqiankun
"
$ yarn add qiankun # 或者 npm i qiankun -S
"/main.js"
import {
registerMicroApps,
start,
runAfterFirstMounted,
setDefaultMountApp,
initGlobalState,
} from "qiankun";
// 引入我们写好的微应用注册信息
import apps from "@/shared/microApps";
// 注册各个微应用
registerMicroApps(apps);
// 设置主应用启动后默认进入的微应用
setDefaultMountApp(apps[0].activeRule);
// 启动qiankun
start();
"/shared/microApps"
const apps = [
{
name: "micro-juejin-home",
activeRule: "/micro-juejin-home",
entry: `//localhost:8071`,
container: "#subApp",
$meta: {
title: "首页",
},
},
{
name: "micro-juejin-boiling",
activeRule: "/micro-juejin-boiling",
entry: `//localhost::8072`,
container: "#subApp",
$meta: {
title: "沸点",
];
module.exports = apps;
❝❞
name
: Ограничений нет, это хорошо для обеспечения уникальности, но для того, чтобы уменьшить сложность настройки, здесь я выбираю, чтобы оно максимально соответствовало названию проекта и activeRule микроприложенияentry
: URL-адрес входа микро-приложения (то есть адрес, по которому вы можете напрямую открыть микро-приложение)container
: Селектор DOM или узел DOM, который микроприложение подключает к основному приложению.activeRule
: правила активации для микроприложений (эквивалент пути в VueRouter, также поддерживает динамическую маршрутизацию)$meta
: (Примечание) Это не официальная конфигурация, это атрибут информационной записи, когда я инициализирую леса, например заголовок, который можно использовать в качестве панели навигации.
"Доступ к микроприложениям"
"main.js"
import "./public-path";
import Vue from "vue";
import VueRouter from "vue-router";
import App from "./App.vue";
import { routes } from "./router";
import store from "@/store";
Vue.config.productionTip = false;
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
const packageName = require("../package.json").name;
let router = null;
let vm = null;
// 将创建Vue根实例并挂载封装成可调用的函数
function VueRender(props = {}) {
const { container } = props;
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? `/${packageName}` : "", // 这个需要与主应用中注册的微应用的activeRule一致
mode: "history",
routes,
});
vm = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector("#app") : "#app");
}
// 如果不作为微应用加载则直接调用VueRender
if (!window.__POWERED_BY_QIANKUN__) {
VueRender();
}
// 微应用必须暴露的三个加载生命周期hooks
export async function bootstrap() {
console.log("[vue] vue app bootstraped");
}
export async function mount(props) {
console.log("[vue] props from main framework", props);
VueRender(props);
}
export async function unmount() {
vm.$destroy();
vm = null;
router = null;
}
❝❞
__webpack_public_path__
Это очень важно и определяет путь загрузки статических ресурсов в микроприложении, таких как:![]()
-
VueRouter中的base
в микроприложении для регистрации в основном приложенииactiveRule
Соответственно, здесь я использую имя пакета микроприложения в качестве префикса пути, чтобы упростить инициализацию конфигурации в инструменте формирования шаблонов. -
bootstrap
,mount
,unmount
загружается как микроприложение и должно быть доступноqiankun
Жизненный цикл признанияhooks
"запросить прокси"
Эта часть тоже очень важна, и это тоже яма, на которую наступили в процессе практики.
❝Одна вещь, которую вы должны знать о построении архитектуры микроинтерфейса в qiankun:"Все запросы начинаются с
主应用的域
инициированный"
Итак, нам нужно сделать две вещи:❞
- Микроприложения настраивают заголовки междоменных ответов.
- Двойное проксирование асинхронных запросов API
"Заголовок междоменного ответа конфигурации микроприложения"
Основное приложение загружает микроприложение какfetch
метод, поэтому вам нужно добавить разрешение для микроприложения跨域
просил响应头
.
кmicro-juejin-home
из"vue.config.js"Например:
module.exports = {
devServer: {
headers: {
//指定允许其他域名访问
//一般用法(*,指定域,动态设置),3是因为*不允许携带认证头和cookies
"Access-Control-Allow-Origin": "http://localhost:8088",
//是否允许后续请求携带认证信息(cookies),该值只能是true,否则不返回
"Access-Control-Allow-Credentials": true,
},
// something else ...
}
"Двойное проксирование асинхронных запросов API"
Запрос, инициированный в микроприложении, можно понимать как отправленный от имени основного приложения, поэтому нам нужно сделать здесь两次代理
Сначала"Прокси основного приложения для микроприложения", то из"Прокси-сервер Microapp на адрес сервера"
- "Прокси основного приложения для микроприложения":
в основном приложенииvue.config.js
:
module.exports = {
devServer: {
proxy: {
"/api/micro-juejin-home": {
target: "http://localhost:8071",
ws: false,
changeOrigin: true,
},
"/api/micro-juejin-boiling": {
target: "http://localhost:8072",
changeOrigin: true,
ws: false,
},
//其他微应用同理...
},
// something else ...
},
};
- "Прокси-сервер Microapp на адрес сервера"
микро приложениеmicro-juejin-home
серединаvue.config.js
Например:
module.exports = {
devServer: {
proxy: {
"/api/micro-juejin-home": {
target: "http://localhost:3000",
ws: false,
changeOrigin: true,
pathRewrite: {
'^/api/micro-juejin-home': "/api"
}
},
},
// something else ...
},
};
❝Здесь вы можете
api
Написание асинхронного запроса и настройка прокси будут немного запутанными, но у меня есть причина сделать это:❞
- почему в
/api
добавить после/micro-juejin-home
?Микроприкладной项目名称
так как"логотип", чтобы основное приложение могло корректно识别
какое микроприложение инициировало эти асинхронные запросы, и代理
Дать соответствующий микроаксид, позвольте ему управлять собойapi
.- API для решения различных микроприложений"конфликт имен"проблема, не нужно рассматривать микро-приложение
api
Будь ли и другие микро-приложения重名
Действительно микро-приложения нужно только управлять своими на линии.- позволяет микрофронтендам лучше взаимодействовать с"Микросервисы"Объединить
❝"Nginx"То же самое относится и к прокси-серверу . Конкретные файлы конфигурации см. в различных"nginx.conf"
❞
"связь между приложениями"
Связь между приложениями осуществляется через глобальный"state"из"модель публикации-подписки"для достижения этой цели"state"и опубликовать и подписаться наqiankun
некоторые при условии"api"Заканчивать:
-
initGlobalState(state)
Определяем глобальное состояние и возвращаем способ связи, рекомендуется использовать его в основном приложении, а микроприложение получает способ связи через реквизиты. -
onGlobalStateChange(callback)
Отслеживает глобальное состояние в текущем приложении, и изменение вызывает обратный вызов -
setGlobalState(state)
Установите глобальное состояние в соответствии с атрибутом первого уровня, и только существующий атрибут первого уровня может быть изменен в микроприложении. это похоже"react"середина"setState", метод"state"Параметры могут быть全局state的一部分
, а затем изменить属性值
. -
offGlobalStateChange()
Убрать мониторинг состояния текущего приложения, которое будет вызываться по умолчанию при размонтировании микроприложения.
"Использование в основном приложении"
"Использование в микроприложениях"
Использование его в микроприложении почти такое же, как и в основном приложении, за исключением того, что нет необходимости инициализировать состояние, вы можете использовать его в микроприложенииmount
Получить и разоблачить в этом крючке жизненного цикла监听全局state
а также改变全局state
Методы.
Например, кусок кода, который я использую в своем проекте:
// main.js
// ...
// 这里用export暴露给子组件调用,下同
export let onGlobalStateChange;
export let setGlobalState;
export async function mount(props) {
onGlobalStateChange = props.onGlobalStateChange;
setGlobalState = props.setGlobalState;
VueRender(props);
//这里加载完毕后可以改变全局的状态通知主应用让其Loading组件消失
setGlobalState({ isLoadingMicro: false });
}
export async function unmount() {
instance.$destroy();
instance = null;
router = null;
//这里微应用注销后通知主应用让其Loading组件出现
setGlobalState({ isLoadingMicro: true });
}
❝пройти через
❞qiankun
это при условииAPI
достаточно для завершения межприложения通信
. На самом деле, с инженерной точки зрения, мы должны свести к минимуму связь каждого микроприложения, чтобы каждый микроответ выглядел болееDRY
, даже в обычных SPA-проектах.
наконец
На самом деле, есть еще много подробностей, которыми я хочу поделиться, но у меня нет другого выбора, кроме как ограничить количество слов.Я надеюсь, что однажды большие самородки смогут отлично поддержать mdnice (ушла ночь, чтобы отфильтровать тысячи избыточного CSS, и меня стошнило).
Хотя на написание этой статьи ушло много времени и усилий, ваш"подобно"Это мотивация продолжать делиться.
Кроме того, я слышал, что людям, которые любят звезду ⭐, не будет невезения."Портал GitHub"
-
"
生产环境
":"Самородки (MicroApps): www.channing-bbs.club"
🏆 Технический специальный выпуск 4 | Расскажите о тех вещах, которые касаются микроинтерфейса...