@Dale-Lin
2022-03-09T11:50:38.000000Z
字数 2846
阅读 967
微前端
bootstrap、mount、unmount 三个声明周期钩子,以供主应用调用。
/** 只在微应用初始化时调用一次,重新进入时会调用 mount */export const bootstrap = async () => {console.log('bootstraping')}/** 每次进入都会调用 mount 钩子,通常在这里渲染应用 */export const mount = async (props) => {ReactDOM.render(<App />, props.container)}/** 每次切出/卸载会调用的方法,通常在这里卸载应用实例 */export const unmount = async (props) => {ReactDOM.unmountComponentAtNode(props.container)}/** 仅当使用 loadMicroApp 方式加载微应用时生效 */export const update = async (props) => {console.log('update props')}
public-path.js,以修改运行时 publicPath 处理微应用资源路径,需要在入口文件处引用:
// public-path.jsif (window.__POWERED_BY_QIANKUN__) {__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN}
// index.tsimport './public-path'// ......
output.library 和 output.libraryTarget 修改:
const pkgName = require('./package.json').namelet publicPath = '/' // devif (process.env === 'production') {publicPath = 'https://cdn.example.com/${pkgname}/'}module.exports = {output: {publicPath: publicPath,library: pkgName,libraryTarget: 'window',}}
qiankun:
$ yarn add qiankun
import { registerMicroApps, start } from 'qiankun'// 注册微应用// qiankun 会取 container 字段对应的 DOM 节点,传给微应用的 props.containerregisterMicroApp([{name: 'sizeChartService',entry: "https://cdn.example.com/app1/index.html",container: '#container',activeRule: '/sizeChart',props: {// 主应用传给微应用的数据}},{name: 'workflowService',entry: "https://cdn.example.com/app2/index.html",container: '#container',activeRule: '/workflow'}], {// 微应用暴露的生命周期钩子beforeLoad: () => Promise<any>,beforeMount: () => Promise<any>,afterMount: () => Promise<any>,beforeUnmount: () => Promise<any>,afterUnmount: () => Promise<any>,})// 启动 qiankun,参数都可选start({// 是否开启沙箱模式sandbox: false,// 自定义 fetch 微应用资源的方法fetch: (entry) {// 请求资源带 timestamp 保证最新return window.fetch(`${entry}?timestamp=${Date.now()}`)}})
activeRule 可以是一个接受 loction 对象的函数,在例如主应用是 hash 路由时, 可以通过一个函数返回 true/false 的方式来动态控制:
const getHashActiveRule = (activeHash) => (location) => location.hash.startsWith(activeHash)registerMicroApp([{name: 'hashApp',entry: 'https://cdn.example.com/hashApp/index.html',container: '#container',activeRule: getHashActiveRule('#/hashActivePrefix/hashApp')}])
如果微应用同时在 hash 路由和 history 路由的容器环境使用,内部其实需要根据容器路由模式判断使用
<BrowserRouter>或<HashRouter>。
loadMicroApp(microApp[, configuration]) 加载微应用:
import { loadMicroApp } from 'qiankun'// ...const [microApp, setMicroApp] = useState(null)const container = useRef(null)useEffect({if (container.current) {const app = loadMicroApp({// 必选,微应用的唯一名称name: 'sizeChartService',// 必选,微应用入口资源entry: `https://cdn.example.com/microAppName/index.html?timestamp=${Date.now()}`,// 必选,容器节点选择器或是 DOM 节点的 ref.currentcontainer: containerRef.current,// 可选,传给微应用的属性props: {}}, {// configuration 同 qiankun.start// ...})setMicroApp(app)}}, [container])useEffect(() => () => {// 组件卸载时需要手动卸载微应用if (microApp) microApp.unmount()}, [microApp])
如果微应用暴露了 update 生命周期钩子,还可以在主应用调用 microApp.update({ ...props }) 更新。
在一个路由下需要渲染多个微应用时,就必须使用手动挂载方式