背景
由于在 《吐槽一次qiankun微前端的框架》 这篇博客中,初次使用qiankun,然后接入了原生项目作为微服务的应用到主应用,所以就想着出个系列篇
目的
- 介绍利用qiankun框架, vue3 项目应用作为微应用,怎么接入到主应用
- 将我个人的应用整到一个大集合中
技术栈
-
微应用:vue3应用
-
@vue/[email protected]
-
sass
-
node版本 16.x
-
主应用:react
-
sass
-
node版本 22.x
配置前阅读
此次使用qiankun,并不是与路由挂钩,微服务内的路由为memoryrouter
微服务配置
主代码如下:
入口文件main.js
import './public-path'
import { createApp } from 'vue'
import App from './App.vue'
import routerInstance from './router'
import store from './store'
let router = null
let instance = null
function render (props = {}) {
const { container } = props
router = routerInstance(!!container)
instance = createApp(App).use(router).use(store).use(MyPlugin)
instance.mount(container ? container.querySelector('#app') : '#app')
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render()
}
export async function bootstrap () {
console.log('[vue] vue app bootstraped')
}
export async function mount (props) {
console.log('[vue] props from main framework', props)
render(props)
}
export async function unmount () {
instance.unmount()
instance = null
router = null
}
public-path.js
,同官方提供的vue2项目无区别
// 是否为微服务被使用
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
route.js
import { createRouter, createMemoryHistory } from 'vue-router'
const routes = [
...
]
export default isMicroApp => {
return createRouter({
history: createMemoryHistory(isMicroApp ? '/micro-vue/' : process.env.BASE_URL),
routes
})
}
说明:
window.__POWERED_BY_QIANKUN__
用来判断我们当前的应用,是否被作为qiankun框架下的微服务所使用,我们的服务中可以通过该判断,去选择开启或关闭某些只适用非微服务下的功能
主应用使用
这里由于我是手动加载微应用,所以直接写了一个MicroApp组件,代码如下:
micro-app.tsx
其中$$cacheLifecycleByAppName
配置,看完上节的同学应该是知道的,当然如果觉得麻烦,并且没有设计到由于缓存导致的页面加载资源失效问题,可以直接忽略
import React, { useRef, useEffect } from "react";
import { loadMicroApp, type MicroApp } from "qiankun";
interface IProps {
/** 微服务url */
url: string;
/** 微服务是否缓存 默认不开启 */
isCache?: boolean;
/** 微服务名称 */
name: string;
/** 开启样式隔离,默认关闭 */
strictStyleIsolation?: boolean;
}
/**
* @abstract https://qiankun.umijs.org/zh/api#loadmicroappapp-configuration
*/
function MicroAppComp(props: IProps) {
const { url, isCache = false, name, strictStyleIsolation = false } = props;
const microAppRef = useRef<HTMLDivElement>(null);
const microApp = useRef<MicroApp>();
useEffect(() => {
const init = () => {
if (!microAppRef.current) return;
microApp.current = loadMicroApp(
{
name,
entry: url,
container: microAppRef.current,
},
{
$$cacheLifecycleByAppName: isCache,
sandbox: { strictStyleIsolation },
},
);
};
init();
return () => {
microApp.current?.unmount();
};
}, [url]);
return <div ref={microAppRef} key={url} />;
}
export default MicroAppComp;
具体使用:
<MicroApp
url={cpUrl}
name="star"
isCache={true}
strictStyleIsolation={true}
/>
大家可能碰到的问题
- 微应用中用到了fixed定位,怎么修改定位的父元素(祖先)?
通过设置当前微应用的外层元素的 改变堆叠上下文的属性可能会更改fixed定位的基准,如transform不为none。 - 主应用和微应用之间的样式出现混乱?
检查主应用是否使用了css module模块,如果没有使用,使用模块化的css引入来开发,如使用create-react-app脚手架搭建的应用,可以修改css相关文件的后缀,使其接受模块化的引入
*.module.scss
/*.module.css
写到最后
如果大家看到这里,记得给辛苦作文的博主点个赞,你们的支持是我持续更新的最大动力,没有之一!