# qiankun-demo
**Repository Path**: srect/qiankun-demo
## Basic Information
- **Project Name**: qiankun-demo
- **Description**: qiankun demo
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-10-08
- **Last Updated**: 2022-03-09
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## qiankun demo
> 1. [qiankun官方文档](https://qiankun.umijs.org/zh)
> 2. [single-spa](https://zh-hans.single-spa.js.org/docs/getting-started-overview/)
> 3. [微前端-最容易看懂的微前端知识](https://juejin.cn/post/6844904162509979662#heading-0)
微前端的类型:
1. 受路由控制渲染的子应用
2. 不受路由控制的组件
3. 非渲染组件,应用间通信逻辑
### 1.子应用-vue
#### 1. vue-cli创建子应用
```shell
vue create qiankun_vue
```
#### 2. 修改入口`main.js`文件
```javascript
// https://qiankun.umijs.org/zh/guide/tutorial#vue-微应用
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// Vue.config.productionTip = false
let vueInstance = null;
function render(props = {}) {
const { container } = props;
vueInstance = new Vue({
router,
render: h => h(App)
// 这里是挂载到自己的html上,基座会拿到这个挂载后的html,将其插入到相应的容器里
// Application died in status NOT_MOUNTED: Target container with #container not existed after xxx mounted!
// 微应用的根 id 与其他 DOM 冲突。解决办法是:修改根 id 的查找范围。
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 使用 webpack 运行时 publicPath 配置
// 动态设置publicPath
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
// https://qiankun.umijs.org/zh/faq#如何独立运行微应用?
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 暴露3个异步方法 bootstrap mount unmount
export async function bootstrap(props) { }
export async function mount(props) {
console.log('props=====>', props)
render(props);
}
export async function unmount(props) {
vueInstance && vueInstance.$destroy();
}
```
#### 3. 修改路由`router/index.js`文件
```diff
const router = new VueRouter({
mode: 'history',
- base: process.env.BASE_URL,
+ base: window.__POWERED_BY_QIANKUN__ ? '/vue' : process.env.BASE_URL,
routes
})
```
#### 4. 根目录新建`vue.config.js`,修改打包配置
```javascript
module.exports = {
devServer: {
port: 8000,
headers: {
'Access-Control-Allow-Origin': '*'
}
},
// https://webpack.docschina.org/configuration/output/#outputlibrary
configureWebpack: {
output: {
library: 'vueApp', // 打包成一个类库
libraryTarget: 'umd' // umd最终会把bootstrap/mount/unmount挂载到window上
}
}
}
```
### 2.子应用-react
#### 1. create-react-app创建子应用
```
create-react-app qiankun_react
```
#### 2. 修改入口`index.js`文件
```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Link, Route } from 'react-router-dom';
import './index.css';
import App from './App';
// import reportWebVitals from './reportWebVitals';
function render(props) {
const { container } = props;
// https://reactrouter.com/web/api/BrowserRouter
ReactDOM.render(
react-home |
react-about
{/* exact 严格模式 */}
}>
react about page
}>
,
container ? container.querySelector('#root') : document.querySelector('#root')
);
}
// 独立运行
if(!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap(props) { }
export async function mount(props) {
render(props);
}
export async function unmount(props) {
const { container } = props;
ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root'));
}
```
#### 3. 修改打包配置文件
##### 1. 安装`react-app-rewired`
```shell
yarn add react-app-rewired -D
```
##### 2. 子应用根目录新建`config-overrides.js`文件
```javascript
// https://github.com/timarney/react-app-rewired/blob/HEAD/README_zh.md#扩展配置选项
module.exports = {
webpack: config => {
config.output.library = 'reactApp';
config.output.libraryTarget = 'umd';
config.output.publicPath = 'http://localhost:9000/';
return config;
},
devServer: configFunc => {
return (proxy, allowedHost) => {
const config = configFunc(proxy, allowedHost);
// 设置开发服务允许跨域
config.headers = {
'Access-Control-Allow-Origin': '*'
}
return config;
}
}
}
```
##### 3. 设置环境变量
1. 子应用根目录新建`.env`文件
```
PORT=4000
WDS_SOCKET_PORT=4000
```
或者在`package.json`启动脚本中修改端口
```diff
"scripts": {
- "start": "react-app-rewired start",
+ "start": "set PORT=4000 && react-app-rewired start",
},
```
2. 修改`package.json`文件
```diff
"scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
- "eject": "react-scripts eject"
+ "start": "react-app-rewired start",
+ "build": "react-app-rewired build",
+ "test": "react-app-rewired test",
+ "eject": "react-app-rewired eject"
},
```
### 3.子应用(非webpack构建)-jquery+bootstrap
#### 1. 新建`index.html`文件
```html
Bootstrap 101 Template
```
#### 2. 新建`entry.js`入口文件
```javascript
const render = ($) => {
$('#purehtml-container').html("Hello, render with jQuery");
return Promise.resolve();
}
(global => {
global['purehtml'] = {
bootstrap: () => {
console.log('purehtml bootstrap');
return Promise.resolve();
},
mount: () => {
console.log('purehtml mount');
return render($);
},
unmount: () => {
console.log('purehtml unmount');
return Promise.resolve();
},
};
})(window);
```
### 4.基座应用-vue
#### 1.修改入口`main.js`文件
```diff
import Vue from 'vue'
import App from './App.vue'
import router from './router'
+ import { registerMicroApps, start } from 'qiankun';
+ import ElementUI from 'element-ui';
+ import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
+ Vue.use(ElementUI);
+ const apps = [
+ {
+ name: "vueApp",
+ // 默认通过fetch加载这个html,解析里面的js,动态的执行
+ // 注意:子应用必须支持跨域
+ entry: "http://localhost:8000",
+ container: "#vueDOM", // 容器名
+ activeRule: "/vue", // 激活路径
+ props: { a: 1, b: 2 }, // 传给子应用的参数
+ },
+ {
+ name: "reactApp",
+ entry: "//localhost:9000",
+ container: "#react",
+ activeRule: "/react",
+ },
+ {
+ name: "jqueryApp",
+ entry: "//localhost:5000",
+ container: "#jquery",
+ activeRule: "/jquery",
+ props: { a: 100, b: 200 },
+ },
+ ];
+
+ registerMicroApps(apps); // 注册应用
+ // 启动应用
+ start({
+ // https://qiankun.umijs.org/zh/api#startopts
+ prefetch: false, // 取消预加载
+ });
new Vue({
router,
render: h => h(App)
}).$mount('#app')
```
#### 2. 修改`App.vue`组件
```html
base-home
base-about
vue 应用
react 应用
jquery + bootstrap 应用
```