效果
主应用
创建主应用react
npx create-react-app react-app-dase
主应用安装 qiankun
yarn add qiankun # 或者 npm i qiankun -S
根目录新建.env文件
PORT=3010
修改主应用 app.js
import './App.css';
// import { useHistory } from 'react-router-dom'
function App() {
return (
<div className="App">
<a href="http://localhost:3010/micro-app1">跳转到第一个子应用</a>
<hr />
<a href="http://localhost:3010/micro-app2">跳转到第二个子应用</a>
<hr />
<div id='micro-app1'>react1111</div>
<div id='micro-app2'>react2222</div>
</div>
);
}
export default App;
修改主应用 index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'react app', // app name registered
entry: '//localhost:3011',
container: '#micro-app1', //挂载点
activeRule: '/micro-app1',
},
{
name: 'react2 app', // app name registered
entry: '//localhost:3012',
container: '#micro-app2',
activeRule: '/micro-app2',
},
// {
// name: 'vue app',
// entry: { scripts: ['//localhost:3012'] },
// container: '#yourContainer2',
// activeRule: '/yourActiveRule2',
// },
]);
start();
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
子应用创建
创建子应用项目
npx create -react-app react-app-one
根目录新建.env文件
PORT=3010
安装 react-app-rewired
yarn add react-app-rewired -
根目录新建public-path.js
/* eslint-disable no-undef */
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
根目录新建 config-overrides.js
const { name } = require('./package');
module.exports = {
webpack: (config) => {
config.output.library = `${name}-[name]`;
config.output.libraryTarget = 'umd';
// config.output.jsonpFunction = `webpackJsonp_${name}`;
config.output.globalObject = 'window';
return config;
},
devServer: (_) => {
const config = _;
config.headers = {
'Access-Control-Allow-Origin': '*', //解决跨域
};
config.historyApiFallback = true;
config.hot = false;
config.watchContentBase = false;
config.liveReload = false;
return config;
},
};
修改 package.json
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
},
修改index.tsx
import './public-path';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
function render(props: { container?: any; }) {
const { container } = props;
ReactDOM.render(<App />, container ? container.querySelector('#root') : document.querySelector('#root'));
}
export async function bootstrap() {
console.log('[react16] react app bootstraped');
}
export async function mount(props: { container?: any; }) {
console.log('[react16] props from main framework', props);
render(props);
}
export async function unmount(props: { container: any; }) {
const { container } = props;
ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root'));
}
// @ts-ignore
if (!window.__POWERED_BY_QIANKUN__) {
render({});
}
修改 app.tsx
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
我是项目app1111111111
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;