由于目前手里的项目是之前从外包接过来的,是基于qiankun 2.0的微前端项目主应用和子应用都是vue2为技术栈搭建的,由于不支持vite,所以迁移到了micro-app,本来是想等qiankun3.0的,看目前进度有点慢。
微应用img,css使用相对路径被替换为基座应用地址
解决办法就是重写原型链上部分方法和属性替换为子应用地址
//处理img
Object.defineProperty(HTMLImageElement.prototype, 'src', {
set(e) {
const flag = ['http', 'blob:'].every((x) => !e.startsWith(x))
if (window.__MICRO_APP_PROXY_WINDOW__ && e && flag) {
const origin = window.__MICRO_APP_PROXY_WINDOW__.location.origin
e = origin + e
}
this.setAttribute('src', e)
}
})
//处理css
const rawSetAttribute = HTMLLinkElement.prototype.setAttribute
HTMLLinkElement.prototype.setAttribute = function (key, value) {
if (key == 'href' && this.parentNode.tagName.toLowerCase() == 'micro-app-head') {
const origin = window.__MICRO_APP_PROXY_WINDOW__.location.origin
value = value?.replace(window.location.origin, origin)
}
rawSetAttribute.call(this, key, value)
}
微应用使用window.open跳转其他微应用路由
解决办法就是重写window.open地址指向基座应用,因为基座应用路由栈和微应用路由栈是隔离的
//由于microapp沙箱中的window对象是代理,所以子应用的window路由是与主应用隔离的,所以重写open方法
//举个例子:
// const microAppList = [
// {
// name: 'test',
// entry: 'https://xxxx/',
// activeRule: `/index/test`,
// }
// ]
//由于microapp沙箱子应用的window路由是与主应用隔离的,所以重写open方法
const originalWindowOpen = window.open
const ruleSign = '/index/'
const validateStartArr = ['http', ruleSign]
window.open = function (url, target, features) {
const app = microAppList.find((el) => url.startsWith(el.entry))
if (app) {
const wlOrigin = window.location.origin
const origin = !url.includes(ruleSign) ? wlOrigin + app.activeRule : wlOrigin
url = url.replace(app.entry, origin)
} else if (
validateStartArr.every((v) => !url.startsWith(v)) &&
localRoutes.some(({ path }) => !url.startsWith(path) && path != '/')
) {
url = window.location.origin + preApp?.activeRule + url
}
return originalWindowOpen(url, target, features)
}
基座应用和微应用路由跳转和地址同步的问题
因为基座路由栈和微应用路由栈是隔离的,改动每一个微应用代价太大,所以所有跳转统一在基座路由处理
//基座跳转微应用
microApp.router.replace({
name: 'test',
path: 'https://xxx/x?xx=123',
replace: true
})
//微应用跳转微应用建议在路由拦截器,使用history.replaceState将错误路由替换掉
const currentState = history.state || {}
history.replaceState(currentState, document.title, '正确路由')
//微应用内部跳转导致基座应用地址未变更,强制同步
microApp.router.afterEach(() => {
const location = window.__MICRO_APP_PROXY_WINDOW__?.location
const pathname = location?.pathname
if (!location || !preApp || window.location.pathname.includes(pathname || '')) return
const url = preApp?.activeRule + location.pathname + location.search
history.replaceState(history.state || {}, document.title, url)
})
总结:micro-app的坑不比qiankun少,micro-app路由处理尤其麻烦,qiankun路由这一块可以少很多心智负担,至于性能都差不多,内存占用qiankun是最好的,micro-app平均多100mb占用,至于对微应用的改造适配,感觉工作量都差不多,不是网上说的那么简单,总之适合才是最好的