快速上手
基座
搭建项目
- 1、初始化项目
npm init react-app-qiankun-main
- 2、qiankun
yarn add qiankun 或者 npm i qiankun -s
- 3、项目的目录结构(主服务的项目结构
react-app-qiankun-main
├── .env.local // 本地环境
├── .env.development.local // 测试环境
├── .env.production.local // 生产环境
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── components
│ └── Loading.jsx
├── store
│ └── store.js // 主应用的全局状态
├── apps.js // 子应用配置
├── App.css
├── App.js // 基座布局,挂载子应用
├── App.test.js
├── index.css
├── index.js // 主应用中注册微应用
├── logo.svg
├── reportWebVitals.js
└── setupTests.js
基座
.env/.env.development.local (dev和test未做区分)
REACT_APP_SUB_REACT=//localhost:2233/react
REACT_APP_SUB_VUE=//localhost:3344/vue
PORT=1122
- .env.production.local (生产环境)
REACT_APP_SUB_REACT=//localhost:2233/react
REACT_APP_SUB_VUE=//localhost:3344/vue
修改 index.html
挂载dom的默认id,防止与子应用id冲突
// 默认root => main-root
<div id="main-root"></div>
新增store/store.js
见:qiankun.umijs.org/zh/api#init… ,用户主子服务全局数据通信
import { initGlobalState } from 'qiankun';
const initialState = {
user: {
name: 'qiankun'
}
};
const actions = initGlobalState(initialState);
actions.onGlobalStateChange((state, prev) => {
for(const key in state) {
initialState[key] = state[key];
}
})
// 非官方api,https://github.com/umijs/qiankun/pull/729
actions.getGlobalState = (key) => {
return key ? initialState[key] : initialState;
}
export default actions;
修改src/App.js
主要完成基座页面布局及增加挂载子应用的dom(id="subapp-viewport")
const App = (props:any)=> {
return (
<>
<div className="mainapp">
{/* 标题栏 */}
<header className="mainapp-header">
<ul className="mainapp-header-sidemenu">
{/* 侧边栏*/}
</ul>
</header>
<div className="mainapp-main">
{/* 子应用 */}
<main id="subapp-viewport"></main>
</div>
</div>
</>
);
}
增加app.ts
文件,配置相关的子应用
import store from './store/store'
const microApps = [
{
name: 'react',
entry: process.env.REACT_APP_SUB_REACT,
activeRule: '/react',
container: '#subapp-viewport',
},
{
name: 'vue',
entry: process.env.REACT_APP_SUB_VUE,
activeRule: '/vue',
container: '#subapp-viewport',
},
]
const apps = microApps.map(item => {
return {
...item,
props: {
routerBase: item.activeRule,
getGlobalState: store.getGlobalState,
}
}
})
export default apps
主应用中注册微应用,修改[src./index.js]
, registerMicroApps(apps, lifeCycles?)
,具体详见:qiankun.umijs.org/zh/api#regi…
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { registerMicroApps, start, setDefaultMountApp } from 'qiankun';
import apps from './apps'
function render({ appContent, loading }) {
const container = document.getElementById('main-root');
ReactDOM.render(
<React.StrictMode>
<App loading={loading} content={appContent} />
</React.StrictMode>,
container,
)
}
const loader = loading => render({ loading });
render({ loading: true });
const microApps = apps.map((app => ({
...app,
loader,
})))
registerMicroApps(microApps, {
beforeLoad: app => {
console.log('before load app.name=====>>>>>', app.name)
},
beforeMount: [
app => {
console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name)
}
],
afterMount: [
app => {
console.log('[LifeCycle] after mount %c%s', 'color: green;', app.name)
}
],
afterUnmount: [
app => {
console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name)
}
]
})
setDefaultMountApp('/react')
// 启动乾坤
start(opts?)//opts 可选
- 本地启动
npm start
注册React子应用
- 1、初始化项目
npm init react-app react-app-qiankun-sub
- 2.安装
react-app-rewired
、react-router-dom
npm i react-app-rewired --save-dev
npm i react-router-dom --save
- 3.目录结构
react-app-qiankun-sub
├── .env // 本地环境
├── config-overrides.js // 覆盖create-react-app的webpack配置
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── components
│ └── LibVersion.jsx
├── pages
│ └── Home.jsx
├── public-path.js // __webpack_public_path__
├── App.css
├── App.js // 子应用布局
├── App.test.js
├── index.css
├── index.js // 子应用入口,挂载dom导出相应的生命周期钩子
├── logo.svg
├── reportWebVitals.js
└── setupTests.js
- 配置本地环境
[.env]
增加文件,,主要用于配置本地环境,此处的PORT端口好要与基座中的REACT_APP_SUB_REACT
端口保持一致
PORT=2233
- 修改
index.html
挂载dom的默认id,防止与基座及其他子应用id冲突
// 默认root => sub-react-root
<div id="sub-react-root"></div>
- 新增
[src/public-path.js],__webpack_public_path__
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
-
修改
[src/App.js]
主要完成子页面布局 -
修改
[src/index.js]
微(子)应用导出相应的生命周期钩子
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { registerMicroApps, start, setDefaultMountApp } from 'qiankun';
import apps from './apps'
function render({ appContent, loading }) {
const container = document.getElementById('main-root');
ReactDOM.render(
<React.StrictMode>
<App loading={loading} content={appContent} />
</React.StrictMode>,
container,
)
}
const loader = loading => render({ loading });
render({ loading: true });
const microApps = apps.map((app => ({
...app,
loader,
})))
registerMicroApps(microApps, {
beforeLoad: app => {
console.log('before load app.name=====>>>>>', app.name)
},
beforeMount: [
app => {
console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name)
}
],
afterMount: [
app => {
console.log('[LifeCycle] after mount %c%s', 'color: green;', app.name)
}
],
afterUnmount: [
app => {
console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name)
}
]
})
setDefaultMountApp('/react')
start();
- 增加
[config-overrides.js]
,覆盖create-react-app的webpack配置
const { name } = require('./package');
module.exports = {
webpack: config => {
config.output.library = `${name}-[name]`;
config.output.libraryTarget = 'umd';
config.output.jsonpFunction = `webpackJsonp_${name}`;
return config;
},
devServer: (configFunction) => {
return (proxy, allowedHost) => {
const config = configFunction(proxy, allowedHost);
config.historyApiFallback = true;
config.open = false;
config.hot = false;
config.watchContentBase = false;
config.liveReload = false;
config.headers = {
'Access-Control-Allow-Origin': '*',
};
return config;
}
}
}
- 修改
package.json
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start", //重写start
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
},
- 本地启动
npm start
添加vue子应用
- 初始化子应用
npm install -g @vue/cli-service-global
vue create vue-cli-qiankun-sub
- 2.安装
vue-router
npm i vue-router --save
- 3.目录结构
vue-cli-qiankun-sub
├── .env // 本地环境
├── vue.config.js // vue可选的配置文件
├── babel.config.js
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── components
│ └── HelloWorld.vue
├── router
│ └── index.js
├── views
│ └── Home.vue
├── public-path.js // __webpack_public_path__
├── App.vue // 子应用布局
└── main.js // 子应用入口,挂载dom导出相应的生命周期钩子
🌮 vue子应用(开撸代码)
-
新增1个.env文件,主要配置本地环境
此处PORT需要和基座
REACT_APP_SUB_VUE
端口保持一致PORT=3344
- 修改
index.html
挂载dom的默认id,防止与基座及其他子应用id冲突
// 默认root => sub-vue-root <div id="sub-vue-root"></div>
- 修改
-
新增[src/public-path.js],webpack_public_path
if (window.__POWERED_BY_QIANKUN__) { // eslint-disable-next-line no-undef __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; }