Введение
Я недавно работал над проектом микроинтерфейса, и я действительно наступил на много ям в процессе.Я пытался и делал ошибки в ограниченных данных, и я молчал и две строки слез ха-ха.Я буду запишите все ямы на этот раз, чтобы больше людей и меньше людей совершили обход, этот проект используетМуравей ФинансовыйКак фундамент как развитие.Нечего сказать, давайте поговорим!!!
Так что же такое цянькунь?
qiankun — это библиотека для реализации микроинтерфейса, основанная на single-spa, цель которой — помочь вам более легко и безболезненно создать готовую к производству систему архитектуры микроинтерфейса.
Что такое микрофронтенд
Архитектура микроинтерфейса имеет следующие основные ценности:
-
Независимость от стека технологий
Основная структура не ограничивает технологический стек приложения доступа, а микроприложение имеет полную автономию.
-
Независимая разработка, независимое развертывание
Хранилище микроприложений является независимым, а интерфейс и серверная часть могут разрабатываться независимо.После завершения развертывания основной фреймворк автоматически завершает обновление синхронизации.
-
Инкрементное обновление
Перед лицом различных сложных сценариев нам обычно сложно полностью обновить или рефакторить существующую систему, а микро-фронтенд — очень хорошее средство и стратегия для реализации инкрементного рефакторинга.
-
При самостоятельном беге
Изоляция между каждым микродатчиком, состояние не передается во время выполнения
Взято изофициальная документация qiankun
Основная конфигурация приложения
Основное приложение и подприложение этого проекта — vue,
скачать qiankun
npm install qiankun
Зарегистрируйте микроприложение в основном приложении
// 导入乾坤函数
import {
registerMicroApps,
setDefaultMountApp,
start
} from "qiankun";
Инкапсулировать метод рендеринга
Этот метод изначально вызывается один раз в main.js, в основном используется для монтирования основного приложения, а затем по очереди вызываются подприложения, поэтому судить претенциозно.Передаются параметры HTML и состояние загрузки подприложение соответственно.content
Мы используем vuex для хранения полей для удобства использования
let app = null;
function render({ appContent, loading }) {
if (!app) {
app = new Vue({
router,
store,
render: h => h(App),
}).$mount('#app');
} else {
store.commit('microApp/changeCenter', appContent);
store.commit('microApp/changeLoading', loading);
}
}
Регистрация микроприложения
Приведенные ниже приложения можно использовать для регистрации микроприложения после получения данных.Случай в этой статье относительно прост, что удобно для понимания всем.
В параметрах **контейнер и рендер** зарегистрированного самоприложения есть множество ям для майнинга, о чем будет рассказано ниже.
function genActiveRule(routerPrefix) {
return location => location.pathname.startsWith(routerPrefix);
}
//传递给子应用的数据
let msg = {
![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/4/27/171bbc5de042ec98~tplv-t2oaga2asx-image.image)
data:'修炼爱情的辛酸,学会放好以前的渴望'
}
let apps = [
{
name: 'linjunjie',
entry: '//localhost:215', // 改成自己子应用的端口号
container:'#subView', //节点 id // 沙盒模式
// render:render, // 普通模式
activeRule: genActiveRule('/star'),
props:msg
}
]
//注册的子应用 参数为数组
registerMicroApps(apps,{
beforeLoad: [
app => {
console.log(app)
console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
},
],
beforeMount: [
app => {
console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
},
],
afterUnmount: [
app => {
console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
},
],
});
setDefaultMountApp('/star/linjunjie')
//开启沙盒模式
start({
sandbox :{strictStyleIsolation: true}
})
После регистрации информации о микроприложении, как только URL-адрес браузера изменится, логика сопоставления qiankun будет автоматически запущена, и все микроприложения, соответствующие правилу activeRule, будут вставлены в указанный контейнер, а микро- приложения будут вызываться по очереди для раскрытия ловушек жизненного цикла.
Элементы отображения, подготовленные основным приложением для подприложений
<template>
<div id="app">
<div id="nav">
<!--//主应用 为子应用的跳转dom-->
<div @click="onChangePage('/star/linjunjie')" >林俊杰</div>
<div @click="onChangePage('/star/zhangyixin')" >张艺兴</div>
</div>
<!--//用来展子应用的 内容区-->
<div id="subView" class="sub-content-wrap" v-html="content"></div>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default{
data(){
return {
}
},
computed:{
//获取子应用HTML 数据
...mapState('microApp', ['content']),
...mapState('microApp', ['mircoAppLoading']),
},
methods:{
//定义跳转方法
onChangePage(url){
console.log(url)
this.routerGo(url, '我喜爱的男明星')
},
routerGo(href = '/', title = null, stateObj = {}) {
window.history.pushState(stateObj, title, href);
},
}
}
</script>
Конфигурация вспомогательного приложения
Конфигурация подприложения относительно проста, дополнительная загрузка qiankun не требуется, а лайфхук можно экспортировать.
Жизненный крючок, который экспортирует ответ
экспортbootstrap
,mount
,unmount
Три хука жизненного цикла для вызова основного приложения в нужное время.Обратите внимание, что при создании экземпляра маршрута считается, что при работе в среде qiankun маршрут должен иметь префикс, и префикс согласуется с параметрами в функции подприложения регистрации основного приложения genActiveRule("/subdemo")
Значение «звездочка» должно соответствовать значению основного приложения. Значение в genActiveRule("/star") должно быть согласовано и использоваться как основным приложением, так и микроприложением.
Если новый VueRouter не настроен в main.js, переместите эту конфигурацию в main.js для упрощения управления.
import routes from './router' //将路由信息导出方便使用
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/star' : '/',
mode: 'history',
routes,
});
instance = new Vue({
router,
store,
render: h => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}else{
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
//props 包含主应用传递的参数 也包括为子应用 创建的节点信息
console.log(props)
render(props);
}
export async function unmount() {
instance.$destroy();
instance = null;
router = null;
}
Настройка инструментов упаковки для микроприложений
В дополнение к предоставлению соответствующих ловушек жизненного цикла в коде, чтобы основное приложение могло правильно идентифицировать некоторую информацию, предоставляемую микроприложением, инструмент упаковки микроприложений должен добавить следующую конфигурацию в vue.config.js:
const packageName = require('./package.json').name;
module.exports = {
output: {
library: `${packageName}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`,
},
};
Решение по подзаявке
Создайте новый publicPath.js в подприложении и введите его в main.js
if (window.__POWERED_BY_QIANKUN__) {
//处理资源
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
Решение проблем с загрузкой ресурсов
настроить vue.config.js
module.exports = {
publicPath:`//localhost:${port}`,
}
vue.config.js полная конфигурация
const path = require('path');
const packageName = require('./package').name;
function resolve(dir) {
return path.join(__dirname, dir);
}
const port = 7101; // dev port
module.exports = {
publicPath:`//localhost:${port}`,
outputDir: 'dist',
assetsDir: 'static',
filenameHashing: true,
devServer: {
// host: '0.0.0.0',
hot: true,
historyApiFallback: true,//添加 重点
port,
overlay: {
warnings: false,
errors: true,
},
headers: {
'Access-Control-Allow-Origin': '*',
},
},
configureWebpack: {
resolve: {
alias: {
'@': resolve('src'),
},
},
output: {
library: `${packageName}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`,
},
},
};
Пит-рекорд
Если текущая страница является подприложением, обновите страницу 404.
Следующие методы настроены для основного приложения
-
Метод 1 Удалить элемент конфигурации в режиме
mode: 'history', // 将此配置代码删除
-
Способ 2: настроить страницу 404
Если не закомментироватьmode: 'history'
этот параметр
Перенаправить страницу 404 на главную
{
path: '*',
name: 'indexNotFound',
component: resolve => require(['@/components/home'], resolve),
children: HomeChild,
},
Обнаружены проблемы с изоляцией в стиле подприложений при запуске режима песочницы
-
Основная конфигурация приложения
sandbox :{strictStyleIsolation: true}
Режим рендеринга изменен с режима рендеринга на контейнерcontainer:'#subView'
, В это время установленный дом поддержания<div id="subView"> </div>
Запомнить основной контейнер :#+id -
Конфигурация вспомогательного приложения Основной перехват кода, упомянутый выше
instance = new Vue({ router, store, render: h => h(App), }).$mount(container ? container.querySelector('#app') : '#app'); //重点 `` 遇到的问题: 开启沙箱模式,如果是 采用 render 模式会报错 ,固选择container 模式
визуализация
Написал сюда, проект построен, посмотрим на эффект
Вот полный код для всех, чтобы узнатьАдрес кода на гитхабе
проблема проекта
-
Почему я не вижу эффекта суб-приложения после запуска проекта
Измените номер порта субприложения, зарегистрированного в основном приложении main.js мастера, на номер порта вашего собственного проекта.
Эпилог
Есть и другие ямки в разработке.Забыл записать.Обязательно помните о кроссдоменной проблеме ресурсов подприложения развертывания проекта, которая требует Nginx для настройки кроссдоменных проблем.
Ученик начальных классов в мире фронтенда!!!