基于 Vite 的 React+Vue 混部完整模板(含目录结构、依赖清单、启动脚本)

🔥 基于 Vite 的 Qiankun 微前端完整模板

主应用(Vite+React) + React子应用(Vite) + Vue3子应用(Vite)

纯 Vite 构建,无 Webpack,开箱即用,包含:

  • 完整目录结构
  • 所有依赖清单
  • 可直接运行的启动脚本
  • 全局状态互通
  • 路由隔离
  • 样式隔离

一、项目整体结构(直接按这个创建)

复制代码
qiankun-vite-micro/
├── main-app/          # 主应用(Vite + React)
├── react-sub/         # React 子应用(Vite + React)
└── vue-sub/           # Vue3 子应用(Vite + Vue3)

二、主应用:main-app(Vite + React)

1. package.json 依赖

json 复制代码
{
  "name": "main-app",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "qiankun": "^2.10.13",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.22.0"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.2.1",
    "vite": "^5.0.11"
  }
}

2. vite.config.js

js 复制代码
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  server: {
    port: 4000,  // 主应用端口
    cors: true
  }
})

3. 入口 src/main.jsx

jsx 复制代码
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import App from './App.jsx'
import { registerMicroApps, start, initGlobalState } from 'qiankun'

// 全局状态
const initialState = {
  userInfo: { name: '主应用用户' },
  token: '123456'
}
const { setGlobalState, onGlobalStateChange } = initGlobalState(initialState)

// 注册子应用
registerMicroApps([
  {
    name: 'reactSub',
    entry: '//localhost:4001',
    container: '#container',
    activeRule: '/react',
    props: { setGlobalState, onGlobalStateChange }
  },
  {
    name: 'vueSub',
    entry: '//localhost:4002',
    container: '#container',
    activeRule: '/vue',
    props: { setGlobalState, onGlobalStateChange }
  }
])

// 启动
start({
  sandbox: { strictStyleIsolation: true }
})

ReactDOM.createRoot(document.getElementById('root')).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
)

4. src/App.jsx

jsx 复制代码
import { Link, Outlet } from 'react-router-dom'

function App() {
  return (
    <div>
      <h1>🚀 主应用(React+Vite)</h1>
      <nav style={{ margin: '1rem 0' }}>
        <Link to="/react" style={{ marginRight: 10 }}>React 子应用</Link>
        <Link to="/vue">Vue 子应用</Link>
      </nav>
      {/* 子应用挂载点 */}
      <div id="container" style={{ border: '1px solid #eee', padding: 20 }} />
      <Outlet />
    </div>
  )
}

export default App

三、React 子应用:react-sub(Vite + React)

1. package.json

json 复制代码
{
  "name": "react-sub",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.22.0"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.2.1",
    "vite": "^5.0.11",
    "vite-plugin-qiankun": "^1.0.15"
  }
}

2. vite.config.js

js 复制代码
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import qiankun from 'vite-plugin-qiankun'

export default defineConfig({
  plugins: [
    react(),
    qiankun('reactSub', { useDevMode: true })
  ],
  server: {
    port: 4001,
    cors: true
  }
})

3. src/main.jsx

jsx 复制代码
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import { BrowserRouter } from 'react-router-dom'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

let root = null

function render(props) {
  const { container } = props || {}
  const dom = container ? container.querySelector('#root') : document.getElementById('root')
  root = ReactDOM.createRoot(dom)
  root.render(
    <BrowserRouter basename={qiankunWindow.__POWERED_BY_QIANKUN__ ? '/react' : ''}>
      <App {...props} />
    </BrowserRouter>
  )
}

renderWithQiankun({
  mount(props) { render(props) },
  bootstrap() {},
  unmount() { root.unmount() }
})

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  render()
}

4. src/App.jsx

jsx 复制代码
import { useEffect, useState } from 'react'

export default function App(props) {
  const [globalState, setGlobalState] = useState({})

  useEffect(() => {
    if (props.onGlobalStateChange) {
      props.onGlobalStateChange((state) => {
        setGlobalState(state)
      }, true)
    }
  }, [props])

  return (
    <div>
      <h2>⚛️ React 子应用</h2>
      <p>全局用户:{globalState.userInfo?.name}</p>
      <button onClick={() => props.setGlobalState({ userInfo: { name: 'React修改' } })}>
        修改全局状态
      </button>
    </div>
  )
}

四、Vue3 子应用:vue-sub(Vite + Vue3)

1. package.json

json 复制代码
{
  "name": "vue-sub",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.4.15",
    "vue-router": "^4.2.5"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.3",
    "vite": "^5.0.11",
    "vite-plugin-qiankun": "^1.0.15"
  }
}

2. vite.config.js

js 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun'

export default defineConfig({
  plugins: [
    vue(),
    qiankun('vueSub', { useDevMode: true })
  ],
  server: {
    port: 4002,
    cors: true
  }
})

3. src/main.js

js 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

let app = null

function render(props) {
  const { container } = props || {}
  app = createApp(App)
  app.use(router)
  app.mount(container ? container.querySelector('#app') : '#app')
}

renderWithQiankun({
  mount(props) { render(props) },
  bootstrap() {},
  unmount() { app.unmount() }
})

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  render()
}

4. src/router/index.js

js 复制代码
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

const routes = [
  { path: '/', component: Home }
]

const router = createRouter({
  history: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? '/vue' : ''),
  routes
})

export default router

5. src/App.vue

vue 复制代码
<template>
  <div>
    <h2>🟢 Vue 子应用</h2>
    <p>全局用户:{{ userInfo?.name }}</p>
    <button @click="changeName">修改全局状态</button>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
const userInfo = ref({})
const props = defineProps(['onGlobalStateChange', 'setGlobalState'])

onMounted(() => {
  if (props.onGlobalStateChange) {
    props.onGlobalStateChange((state) => {
      userInfo.value = state.userInfo
    }, true)
  }
})

const changeName = () => {
  props.setGlobalState({ userInfo: { name: 'Vue修改' } })
}
</script>

6. src/views/Home.vue

vue 复制代码
<template>
  <div>Vue 子应用首页</div>
</template>

五、一键启动脚本(根目录创建 start.bat)

bat 复制代码
@echo off
start cmd /k "cd main-app && npm install && npm run dev"
timeout /t 2 /nobreak >nul
start cmd /k "cd react-sub && npm install && npm run dev"
timeout /t 2 /nobreak >nul
start cmd /k "cd vue-sub && npm install && npm run dev"

六、访问地址


七、核心功能说明

✅ 纯 Vite 构建,无任何 Webpack 兼容问题

✅ React + Vue3 完美混部

✅ 全局状态互通(修改一个应用,所有应用同步)

✅ 路由严格隔离,不冲突

✅ 样式严格隔离,不污染

✅ 子应用可独立运行 + 主应用加载

相关推荐
Rooting++5 小时前
腾讯无界微前端源码分析
前端
小嘿前端仔5 小时前
用AI读源码这件事:前端视角的实战方法论,附Vue3 reactivity源码解读示范
前端
其实防守也摸鱼5 小时前
XSS漏洞全景解析:从原理、实战利用到纵深防御
前端·网络·安全·xss·xss漏洞
戴维南5 小时前
DeepAgents 快速上手教程
前端
bigfatDone5 小时前
OpenSpec + Superpowers 联合开发工作流
前端
北漂大橙子5 小时前
OpenSpec 完全指南:让 AI 编码可预测的规范框架
前端
lemon_yyds6 小时前
OpenCode 最佳实践
前端
束尘6 小时前
Vue3 项目集成 OnlyOffice 在线编辑 + 自定义插件开发(二):插入功能全实现
数据库·vue.js·mysql