Микро-интерфейс — это технические средства и методическая стратегия, позволяющая нескольким командам совместно создавать современные веб-приложения путем независимой публикации функций.
Микроинтерфейс имеет следующие характеристики:
Выше приведено краткое описание микроинтерфейса с официального сайта qiankun.
В качестве примера мы возьмем vue2.x + qiankun.
Давайте сначала воспользуемся им vue-cli быстро создает проект для основного приложение, здесь его зовут main-app
sh
копироватькод
vue create main-app
Чтобы быть ближе к реальному проекту, мы временно решили установить их вручную.
После создания проекта мы main-app копироватьработадлясубприложение,Изменить имядля дополнительное приложение, теперь у нас есть main-app основное приложениеи sub-app субприложение。
Ладно, основная подготовительная работа завершена, приступаем к трансформации в микро-фронтенд-приложения на основе двух только что созданных нами проектов.
В главном приложении установите qiankun:
sh
копироватькод
yarn add qiankun # или npm i qiankun -S
Оглавление src Создать новый под src/qiankun/index.js
Зарегистрируйтесь и запустите микроприложение, код следующий:
js
копироватькод
import { registerMicroApps, start } from "qiankun";
import store from "@/store";
registerMicroApps([
{
name: "sub-app",
entry: "http://localhost:7663", // Вход в микроприложение
container: "#subapp-viewport", // Монтаж микроприложений издив
activeRule: "/sub-app/",
props: {
// Здесь Воля родительское приложение из store входящее субприложение
store
}
}
]);
export default start;
Здесь мы определяем префикс маршрутизации микроприложения как sub-app
views Оглавление Создать новый под компонент src/views/qiankun/index.vue
,мы предоставляем id для subapp-viewport контейнер DOM Для субприложения смонтировать
vue
копироватькод
<template>
<div id="subapp-viewport"></div>
</template>
<script>
import start from "@/qiankun/index";
export default {
mounted() {
// запускать Микро-интерфейс if (!window.qiankunStarted) {
window.qiankunStarted = true;
start();
}
}
};
</script>
Найдите папку маршрутизации,router/index.js
Добавьте следующее нижемаршрутизация,для соответствия микроприложениям
js
копировать код
{
путь: "/суб-приложение/*",
meta: { title: "субприложение" },
component: () => import("@/views/qiankun/index")
}
Выше речь идет о Обновление приложения в основном завершено. Далее обновим предыдущее копировать из. sub-app Немного измените его, чтобы сделать его субприложением.
Найти первым /src/router/index.js
, слегка измените файл маршрутизации
удалить
js
копироватькод
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes
});
export default router;
Добавьте в конец файла
js
копироватькод
export default routes;
оказатьсяmain.js
Воля import router from './router'
Исправлятьдля import routes from './router'
и увеличить import VueRouter from "vue-router";
, Здесь мы устанавливаем основное субприложениемаршрутизация для history модель.
удалить:
js
копироватькод
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
Увеличивать
js
копировать код
пусть маршрутизатор = ноль;
пусть экземпляр = ноль;
если (window.__POWERED_BY_QIANKUN__) {
// eslint-отключить-следующую строку
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
функция рендеринга (реквизит = {}) {
const {контейнер} = реквизит;
маршрутизатор = новый VueRouter({
база: window.__POWERED_BY_QIANKUN__ ? "/суб-приложение/" : "/", // Выбросить маршрутизацию плюс префикс
mode: "history",
routes
});
instance = new Vue({
router,
store,
render: h => h(App)
}).$mount(container ? container.querySelector("#app") : "#app");
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export default instance;
export async function bootstrap() {
console.log("[vue] vue app bootstraped");
}
export async function mount(props) {
// props Включатьосновное приложение передать параметры Также включает субприложение Создать из информации об узле
console.log("[vue] props from main framework", props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance = null;
router = null;
}
Окончательный файл main.js изменяется следующим образом.
js
копировать
// main.js
импортировать Vue из «vue»;
импортировать приложение из «./App.vue»;
импортировать маршруты из "./router";
импортировать магазин из "./store";
импортировать VueRouter из «vue-router»;
Vue.config.productionTip = ложь;
// новый вид({
// маршрут,
// store,
// render: h => h(App)
// }).$mount('#app')
// Микро-интерфейс - субприложение Конфигурация
let router = null;
let instance = null;
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
function render(props = {}) {
const { container } = props;
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? "/sub-app/" : "/", // Выбросить маршрутизацию плюс префикс
mode: "history",
routes
});
instance = new Vue({
router,
store,
render: h => h(App)
}).$mount(container ? container.querySelector("#app") : "#app");
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export default instance;
export async function bootstrap() {
console.log("[vue] vue app bootstraped");
}
export async function mount(props) {
// props Включатьосновное приложение передать параметры Также включает субприложение Создать из информации об узле
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
}
существовать sub-app Создать новый под vue.config.js
,Увеличивать Конфигурацияследующее
js
копироватькод
const { name } = require('./package.json')
module.exports = {
publicPath: '/', // Упаковать относительный путь
devServer: {
port: 7663, // Номер работающего порта
headers: {
'Access-Control-Allow-Origin': '*' // Запретить междоменную загрузку
}
},
chainWebpack: config => config.resolve.symlinks(false),
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd', // Упакуйте микроприложения в umd формат библиотеки
jsonpFunction: `webpackJsonp_${name}`
}
}
}
Наконец, мы существуемсубприложениесоздаем тестовую страницу для встраиванияосновного приложение,маршрутизация с предварительным названием /test
vue
копироватькод
// views/sub-app/index.vue
<template>
<div class="sub-app">
Я субприложение
</div>
</template>
<style lang="scss" scoped>
.sub-app {
cursor: pointer;
background-color: aqua;
}
</style>
На данный момент мы знакомы с Трансформация приложения и субприложения в основном завершена, давайте проверим это дальше, мы существуемосновное приложениеиз app.vue
добавить кнопку,заставить его щелкнутьизпора добавить мероприятие this.$router.push('/sub-app/test')
Перейти к субприложению
Нажав кнопку, мы увидим, что субприложение успешно внедрено.
Здесь мы все используем один и тот же стек технологий,Потому что мы делаем то же самое в проектах компании «существовать».,Один и тот же стек технологий можно отделить от общедоступных зависимых библиотек, библиотек пользовательского интерфейса и т. д.,Уменьшите накладные расходы на ресурсы,Улучшите скорость загрузки,Самое главное: «Лучший способ уменьшить конфликты — это объединиться».,Ограничивая стек технологий, мы можем максимально уменьшить конфликты между проектами на ранней стадии проекта.,Снижает рабочую нагрузку и затраты на техническое обслуживание.
Выделение отдельных стилей приложения Платформа Qiankun в определенной степени справилась с этой проблемой. При запуске существующих существует параметр «песочницы». По умолчанию «песочница» может обеспечить изоляцию стилей между сценариями с одним экземпляром. приложениеисубприложение、или Изоляция стиля мультиэкземплярной сцены из субприложения. Если вы хотите решить Для решения вопросов стиля приложений и субприложений в настоящее время существует два способа:
js
копироватькод
{ loader: 'less-loader',
+ options: {
+ modifyVars: {
+ '@ant-prefix': 'yourPrefix',
+ },
+ javascriptEnabled: true,
+ },
}
б. Настройте AntD ConfigProvider.
js
копироватькод
import { ConfigProvider } from 'antd';
export const MyApp = () => (
<ConfigProvider prefixCls="yourPrefix">
<App />
</ConfigProvider>
);
Для конкретной реализации обратитесь к этой статье «Пять методов связи Цянькуня».
Подпроект keep-alive На самом деле я просто хочу его не удалять при переключении, а просто скрыть в стиле (отображение: нет), чтобы в следующий раз он откроется быстрее.
но keep-alive Необходимо использовать с осторожностью, загружая и запуская несколько субприложений одновременно, эта Воля увеличит js/css Риск загрязнения.
Сторона продукта фактически выдвинула это требование в то время, и первое, что тогда пришло на ум, — это использовать qiankun из loadMicroApp Функция ручной загрузки и выгрузки субприложения. но компания из проекта продолжает приложение встраивает дюжину субприложений,Думая о необходимости разобраться с этим один за другим,А ручная погрузка и разгрузка может вызвать некоторые проблемы с границами, которые необходимо решить.,Позже я прямо сказал, что эта нуждаться нехорошо. После этого дело было временно приостановлено.
Конкретные решения можно найти в qiankun issues приведено здесьиз
Нет возможности пройти в существованиесубприложение <router-link>
Или используйте router.push/router.replace
Переходите сразу к из, потому что для этого router это субприложениеизмаршрутизация, все из прыжков будут основаны на субприложениииз base . Конечно, напишите <a>
Ссылки могут переходить в прошлое,но обновлю страницу,Пользовательский опыт не очень хороший.
Здесь можно использовать следующие два метода:
Здесь я инкапсулирую это в широко используемый метод
js
копироватькод
/** * Микро-интерфейссубприложениемаршрутизация Прыжок * @param {String} url маршрутизация
* @param {Object} mainRouter основное приложениемаршрутизация Пример * @param {*} params Объект статуса: информация, передаваемая в целевую маршрутизацию, может быть пустой.
*/
const qiankunJump = (url, mainRouter, params) => {
if (mainRouter) {
// делатьиспользоватьосновное приложениемаршрутизация Пример Прыжок mainRouter.push({ path: url, query: params })
return
}
// Не доставлено приложениемаршрутизация Пример,Традицияпереход в режим
let searchParams = '?'
let targetUrl = url
if (typeOf(params) === 'object' && Object.keys(params).length) {
Object.keys(params).forEach(item => {
searchParams += `${item}=${params[item]}&`
})
targetUrl = targetUrl + searchParams.slice(0, searchParams.length - 1)
}
window.history.pushState(null, '', targetUrl)
}
Найдите пакет vue-pdfizdependenty изvuePdfNoSss.vue.
vue
копироватькод
//Находим пакет vue-pdfиззависимости изvuePdfNoSss.vue
<style src="./annotationLayer.css"></style>
<script>
import componentFactory from './componentFactory.js'
if ( process.env.VUE_ENV !== 'server' ) {
var pdfjsWrapper = require('./pdfjsWrapper.js').default;
var PDFJS = require('pdfjs-dist/es5/build/pdf.js');
if ( typeof window !== 'undefined' && 'Worker' in window && navigator.appVersion.indexOf('MSIE 10') === -1 ) {
// Оригинал комментария из метода введения
// var PdfjsWorker = require('worker-loader!pdfjs-dist/es5/build/pdf.worker.js');
var PdfjsWorker=require('pdfjs-dist/es5/build/pdf.worker.js');
PDFJS.GlobalWorkerOptions.workerPort = new PdfjsWorker();
}
var component = componentFactory(pdfjsWrapper(PDFJS));
} else {
var component = componentFactory({});
}
export default component;
</script>
Исправлятьпроектиз Конфигурациядокументvue.config.js
js
копировать код
цепочкаWebpack: (config) => {
config.module
.rule('worker')
.test(/\.worker\.js$/)
.use('worker-loader').loader('worker-loader')
.options({
inline: true,
fallback: false
}).end();
}
По требованиям заказчика,Иногда серверу может быть запрещено открывать слишком много портов.,Поэтому необходимо развернуть большое приложение и микроприложения вместе.,Поделитесь портом.
хозяинпроекти Подпроектразвертыватьсобраться вместе,Подпроектразвертыватьна второй уровень Оглавление
Потому что forqiankun перехватит загрузку статических ресурсов из,Вместо этого используйте метод выборки для получения ресурсов.,Следовательно, эти ресурсы необходимы для поддержки междоменного,这里我们делатьиспользоватьqiankunпоставлятьиз excludeAssetFilter Воля Добавлен в белый список и выпущен.
(assetUrl: string) => boolean
- Необязательно, укажите некоторые особенности динамической загрузки ресурсов микроприложения (css/js). не быть qiankun Обработка угонаИсправлятьосновное приложение start метод
js
копироватькод
// запускать Микро-интерфейсif (!window.qiankunStarted) {
window.qiankunStarted = true
start({
singular: false,
excludeAssetFilter: (assetUrl) => {
// фильтр Байду
const wihiteWords = ['baidu']
if (wihiteWords.includes(assetUrl)) {
return true
}
return wihiteWords.some(w => {
return assetUrl.includes(w)
})
}
})
}
Некоторые другие часто задаваемые вопросы можно найти на официальном сайте qiankun.
В общем,Микроинтерфейс действительно решил болевые точки в некоторых проектах.,но Помните, что микроинтерфейс — это не панацея,Старые проекты приносят затраты на миграцию,Совместимость различных стеков технологий проекта и решение граничных проблем.,Потому что для нет срочности изнуждаться и получить доступ к микро-интерфейсу.,Это принесет только дополнительную нагрузку,много раз,iframe На самом деле этого вполне достаточно.