写在前面:接触前端开发也有几年了,最近难得有机会使用微前端:当前项目使用vue3,当前有个页面需要使用react组件,项目负责人建议使用react来做,那么这时候方案就来了,iframe和react-dom等也能实现,这不是想到微前端可以独立开发部署,于是乎搜索了下qiankun,教程都说没那么难,那么自己打算开始做一下实践了;
由于需要贴合实际使用场景,所以总结用VUE3+vite作为底座(主应用),vite+react为子应用;
首先是主应用部分: 1、创建vite+vue3的项目:npm create vite vue3-app --tempalte
2、安装依赖:npm i; 然后安装qiankun:npm i qiankun -S
3、需要在主应用中注册为微应用:在入口文件中引入qiankun、注册子应用、启动qiankun;
import {initGlobalState, registerMicroApps, start} from 'qiankun';
registerMicroApps([
{
name: 'react-sub-app', // app name registered
entry: '//localhost:9000',
container: '#react-app',
activeRule: '/react-app',
},
]);
// 启动qiankun
start();
4、在主应用模板中添加子应用的渲染容器
<div>
React 子应用挂载点
<div id="react-app"></div>
</div>
然后在子应用中: 1、创建vite+react的子项目:npm create vite react-sub-app --tempalte
2、安装依赖vite-plugin-qiankun: npm i vite-plugin-qiankun -S;
3、修改vite.config.js配置:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import qiankun from 'vite-plugin-qiankun'
// https://vite.dev/config/
export default defineConfig({
plugins: [
// react({
// jsxRuntime: 'classic', // 确保启用新的 JSX 转换
// }),
qiankun('react-sub-app', {
useDevMode: true
})
],
server: {
port: 9000,
// 允许跨域
cors: true,
// 允许其他地址访问
host: '0.0.0.0',
origin: 'http://localhost:9000', // 添加 origin
headers: {
'Access-Control-Allow-Origin': '*',
},
},
// 关键配置:明确设置构建目标
build: {
target: 'esnext',
rollupOptions: {
external: [], // 确保不排除任何必要的依赖
}
},
define: {
'process.env': {}
},
// 设置base,如果主应用是通过根路径下的某个路径来加载子应用,比如http://localhost:9000/react-sub-app,那么base设置为'/react-sub-app/'
// base: '/react-sub-app/'
})
4、修改入口文件:
import { StrictMode } from 'react'
import React from 'react';
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App.jsx'
import {renderWithQiankun, qiankunWindow} from 'vite-plugin-qiankun/dist/helper'
let root;
function render(props = {}) {
const container = props.container ? props.container.querySelector('#root') : document.getElementById('root');
root = ReactDOM.createRoot(container);
root.render(
<StrictMode>
<App />
</StrictMode>
);
}
// 处理模块加载错误
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
// 在 qiankun 环境中,等待主应用处理完模块加载
// const originalError = console.error;
// console.error = function(...args) {
// if (typeof args[0] === 'string' && args[0].includes('import-html-entry')) {
// return; // 忽略 qiankun 的模块加载错误
// }
// originalError.apply(console, args);
// };
// // 延迟渲染以确保环境稳定
// setTimeout(() => {
// console.error = originalError;
// }, 100);
render();
}
renderWithQiankun({
mount(props) {
console.log('react app mounted');
render(props);
return Promise.resolve();
},
bootstrap() {
console.log('react app bootstraped');
return Promise.resolve();
},
unmount() {
console.log('react app unmounted');
if (root) {
root.unmount();
root = null;
}
return Promise.resolve();
},
update() {
console.log('react app updated');
return Promise.resolve();
}
});
两个应用都顺利起来之后,通过主应用的访问地址后面添加激活的路由:/react-app,访问http://localhost:5173/react-app 最终可以在vue3项目中访问react项目。
第一版先写到这里;后续可以补充踩过的坑,选型原因等
问题一:报错Cannot use import statement outside a module
原因:@vitejs/plugin-react 在开发模式会注入 /@react-refresh 预热脚本(基于 ESModule),而 qiankun 的 import-html-entry 以普通脚本方式 eval 该片段,导致解析失败。
- 解决:微应用开发模式下不启用 React 插件(或至少关闭 Fast Refresh),仅依赖 Vite 对 JSX 的基础处理;保留
vite-plugin-qiankun的useDevMode。- 关闭 React 插件
- 启用 qiankun 插件开发模式
问题二:React is not defined(移除 React 插件后的 JSX 转译)
- 现象:进入子应用时报错:
React is not defined,指向 JSX 渲染位置。 - 原因:在不使用
@vitejs/plugin-react的情况下,JSX 转译输出依赖React.createElement,代码中未引入默认导入React。 - 解决:显式加入默认导入。
- 子应用入口:
micro-react/src/main.jsx:1 - 示例组件:
micro-react/src/App.jsx:1
- 子应用入口: