基于 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 完美混部

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

✅ 路由严格隔离,不冲突

✅ 样式严格隔离,不污染

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

相关推荐
发现你走远了1 分钟前
前端多环境自动化部署实战:GitHub Actions + Azure Blob + Cloudflare
前端·自动化·github
香香爱编程1 分钟前
vue3自定义顶部弹窗
前端·javascript·vue.js
weelinking12 分钟前
【产品】10_搭建前端框架——把你的原型变成真实页面
java·大数据·前端·数据库·人工智能·python·前端框架
蜡台12 分钟前
Vue Echart 的 **高阶组件化** 封装思路
前端·javascript·vue.js·echarts
xuankuxiaoyao13 分钟前
vue.js 路由第二篇
前端·javascript·vue.js
一 乐14 分钟前
图书电子商务网站系统|基于SprinBoot+vue图书电子商务网站设计与实现(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·图书电子商务网站系统
weifengma-wish14 分钟前
通过NPM安装claude code
前端·npm·node.js
yaoxin52112315 分钟前
421. Java 日期时间 API - 包结构 & 方法命名规范
java·前端·python
叫我少年17 分钟前
ASP.NET Core Razor 语法简述
前端
Csvn9 小时前
OpenSpec 详细使用教程
前端