react作为主应用
npx create-react-app react-main
npm i react-router-dom qiankun
registerApp.js
import { registerMicroApps, start } from 'qiankun'
registerMicroApps([{name: 'reactApp',entry: '//localhost:10000',container: '#container',activeRule: '/react'},{name: 'vueApp',entry: '//localhost:5173',container: '#container',activeRule: '/vue'}
], {beforeLoad() {},beforeMount() {},afterMount() {},beforeUnmount() {},afterUnmount() {}
})start()
index.js
import './registerApp'
App.js
import './App.css';
import { BrowserRouter, Link } from 'react-router-dom'function App() {return (<div className="App"><BrowserRouter><Link to="/react" >react</Link><Link to="/vue" >vue</Link></BrowserRouter><div id='container'></div></div>);
}export default App;
子应用
react
npm i rescripts/cli
index.js
import './public-path'
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';function render(props) {const container = props.containerconst root = ReactDOM.createRoot(container?container.querySelector('#root') : document.getElementById('root'));root.render(<React.StrictMode><App /></React.StrictMode>);
}if(!window.__POWERED_BY_QIANKUN__) {render({})
}export async function bootstrap() {}
export async function mount(props) {render(props)
}
export async function unmount() {}
public-path.js
if(window.__POWERED_BY_QIANKUN__) {// eslint-disable-next-line no-undef__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
.env
PORT=10000
WDS_SOCKET_PORT=10000
.rescriptsrc.js
module.exports = {webpack: (config) => {config.output.libraryTarget = 'umd'config.output.library = 'react-f'return config},devServer: config => {config.headers = {"Access-control-Allow-Origin": "*"}return config}}
<BrowserRouter basename={window.__POWERED_BY_QIANKUN__ ? '/child-one' : '/'}>
package.json
"start": "rescripts start",
"build": "rescripts build",
"test": "rescripts test",
"eject": "rescripts eject"
vite 安装的vue3
npm create vue@latest
npm i vite-plugin-qiankun
main.ts
import './public-path'
import './assets/main.css'import { createApp } from 'vue'
import { createPinia } from 'pinia'import App from './App.vue'
import routes from './router'
import { createRouter, createWebHistory } from 'vue-router'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
let app: any
let history: any
let router
function render(props: any) {app = createApp(App)app.use(createPinia())history = createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? '/vue' : '/')router = createRouter({history,routes})app.use(router)const container = props.containerapp.mount(container ? container.querySelector('#app') : '#app')
}renderWithQiankun({mount(props) {render(props)},bootstrap() {console.log('props')},update() {},unmount() {app.unmount()history.destroy()app = nullrouter = null}
})
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {render({})
}
vite.config.ts
import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import qiankun from 'vite-plugin-qiankun'export default defineConfig({plugins: [vue(),vueJsx(),qiankun('vueApp', {useDevMode: true})],server: {// 开发阶段静态资源加载问题origin: '//localhost:5173'},resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}}
})
vue-cli创建vue3项目
vite.config.ts
devServer: {port: 20000,headers: {"Access-Control-Allow-Origin": "*"},},configureWebpack: {output: {libraryTarget: 'umd',library: 'vue-f'}},
public-path.js
if(window.__POWERED_BY_QIANKUN__) {// eslint-disable-next-line no-undef__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
main.ts
import './assets/main.css'import { createApp } from 'vue'
import { createPinia } from 'pinia'import App from './App.vue'
import routes from './router'
import { createRouter, createWebHistory } from 'vue-router'
let app: any
let history: any
let router
function render(props: any) {app = createApp(App)app.use(createPinia())history = createWebHistory(window.__POWERED_BY_QIANKUN__ ? '/vue' : '/')router = createRouter({history,routes})app.use(router)const container = props.containerapp.mount(container ? container.querySelector('#app') : '#app')
}if(!window.__POWERED_BY_QIANKUN__) {render({})}export async function bootstrap() {}export async function mount(props) {render(props)}export async function unmount() {app.unmount()history.destroy()app = nullrouter = null}
static
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="static"></div><script entry>const app = document.getElementById('static')function render() {app.innerHTML = 'static-f'}if(!window.__POWERED_BY_QIANKUN__) {render({})}window['static-f'] = {bootstrap: async () => {},mount: async () => {render({})},unmount: async () => {app.innerHTML = ''},}</script>
</body>
</html>
http-server --port 3000 --cors
app.js
import './App.css';
import { BrowserRouter, Link } from 'react-router-dom'
import { loadMicroApp } from 'qiankun'
import React from 'react'function App() {const containerRef = React.createRef()React.useEffect(() => {loadMicroApp({name: 'static-f',entry: '//localhost:30001',container: containerRef.current})})return (<div className="App"><BrowserRouter><Link to="/react" >react</Link><Link to="/vue" >vue</Link></BrowserRouter><div ref={containerRef}></div><div id='container'></div></div>);
}export default App;