原生 HTML 项目重构:Vue / React 双框架实战指南
这是一个在真实企业项目中非常常见但又极具挑战的场景:
一个历史悠久的原生 HTML + CSS + jQuery 项目(几千行甚至上万行),需要逐步现代化,同时不能停服、不能大重构、不能影响现有业务。
今天我们聊聊渐进式重构的实战路径,重点是Vue 和 React 同时存在于一个项目中的几种可行方案(从简单到复杂)。
1. 为什么会同时需要 Vue 和 React?
| 场景 | 典型原因 | 常见程度(2025-2026) |
|---|---|---|
| 历史包袱 + 新团队偏好 | 老项目用 jQuery,重构中途团队换技术栈 | ★★★★★ |
| 微前端过渡期 | 不同业务线/团队用不同框架 | ★★★★☆ |
| 组件库复用 | 公司内部有成熟的 Vue 组件库,但新项目想用 React | ★★★★☆ |
| 逐步迁移 | 先用一个框架替换部分页面,后期统一 | ★★★★★ |
| 实验/POC | 某些模块试用新框架 | ★★★☆☆ |
结论:Vue + React 同框不是最理想状态,但却是很多中大型项目不得不经历的“过渡形态”。
2. 四种主流共存/重构策略对比
| 策略 | 复杂度 | 停服风险 | 推荐场景 | 长期维护性 | 2025-2026 主流工具 |
|---|---|---|---|---|---|
| 策略1:Vue/React 分别接管独立页面(最推荐入门) | ★★☆☆☆ | 极低 | 页面级迁移 | 中等 | Vite + Vue / Create React App / Vite + React |
| 策略2:微前端(推荐中大型项目) | ★★★★☆ | 低 | 不同子系统/团队 | 高 | single-spa / qiankun / Module Federation |
| 策略3:在 React 里嵌入 Vue(vuera / react-vue) | ★★★☆☆ | 中 | React 为主,想局部用 Vue 组件 | 中低 | vuera / react-vue 等桥接库 |
| 策略4:在 Vue 里嵌入 React(react-in-vue) | ★★★☆☆ | 中 | Vue 为主,想局部用 React 组件 | 中低 | react-in-vue 等 |
推荐路径(根据项目规模):
- 小型/中型项目(<50页):策略1 → 先用一个框架逐步替换页面
- 中大型项目(>50页、多团队):策略2(微前端)→ 最安全、最可扩展
- 临时/实验需求:策略3 或 4
3. 策略1:页面级独立接管(最实用、最低风险)
核心思路:
原生页面 → 逐步替换成纯 Vue 页面或纯 React 页面,路由/入口由后端/ Nginx 控制。
步骤:
- 保留原有结构
原项目保持运行(Apache/Nginx + PHP/静态文件) - 新建 Vue / React 子项目(用 Vite 推荐,启动快)
# Vue 项目
npm create vite@latest my-vue-app -- --template vue-ts
# React 项目
npm create vite@latest my-react-app -- --template react-ts
- 部署到子路径(Nginx 示例)
location /new-vue/ {
proxy_pass http://localhost:5173/; # Vite dev / 构建后 dist
}
location /new-react/ {
proxy_pass http://localhost:3000/;
}
- 逐步迁移
- 先迁移简单静态页 → Vue/React 单页
- 再迁移有交互的模块(表单、列表、弹窗)
- 最后迁移公共组件库(Header/Footer/Nav)
- 公共资源复用
- CSS:提取 common.css → 两个框架都引入
- JS 工具函数:抽成 utils.js → ESM 导入
- 图片/字体:放 public/ 或 assets/
优点:零风险、可并行、可回滚
缺点:用户 URL 会变化(/old → /new-vue),SEO/收藏夹影响
4. 策略2:微前端(single-spa / qiankun / Module Federation)——最推荐长期方案
适用:项目 > 50 页、多个团队维护、未来要统一技术栈但短期无法
single-spa 经典组合(2025-2026 仍然活跃):
- 基座:Vue / React / 纯 HTML 壳
- 子应用:Vue、React、Angular、甚至原生 HTML 都可以
快速上手示例(Vite + single-spa):
- 创建基座(推荐 Vue3 + Vite)
- 子应用分别创建(Vue / React)
- single-spa 注册(简化版)
// register.js
import { registerApplication, start } from 'single-spa';
registerApplication({
name: '@org/vue-app',
app: () => System.import('http://localhost:3001/vue-app.js'),
activeWhen: ['/vue']
});
registerApplication({
name: '@org/react-app',
app: () => System.import('http://localhost:3002/react-app.js'),
activeWhen: ['/react']
});
start();
- 子应用导出(vite.config.js)
// Vue 子应用 vite.config.js
export default defineConfig({
base: '/vue-app/',
build: {
rollupOptions: {
output: {
entryFileNames: '[name].js',
format: 'system'
}
}
}
});
qiankun(阿里系,更适合国内团队):
- 支持 Vue2/3、React、Angular
- 沙箱更完善(js、css 隔离)
Module Federation(Webpack 5+ / Vite 插件):
- 更现代、更细粒度(组件级共享)
- 2025-2026 年大厂微前端首选
5. 策略3/4:框架内嵌另一个框架(桥接方案,谨慎使用)
场景:不想动路由,只想在某个 div 里渲染另一个框架的组件
Vue 里跑 React(react-in-vue 等)
React 里跑 Vue(vuera / react-vue)
示例(React 里嵌入 Vue 组件):
// ReactHost.jsx
import React from 'react';
import { VueInReact } from 'vuera';
import MyVueComponent from './MyVueComponent.vue';
function App() {
return (
<div>
<h1>React 页面</h1>
<VueInReact component={MyVueComponent} prop1="value" />
</div>
);
}
缺点:
- 生命周期冲突
- 状态管理混乱
- 打包体积增大
- 调试痛苦
建议:只在过渡期用,目标是尽快统一到一个框架。
6. 实战建议 & 避坑清单
| 阶段 | 关键动作 | 常见坑 & 解决方案 |
|---|---|---|
| 准备期 | 组件库统一、CSS 变量化、API 抽象 | jQuery 污染全局 → 逐步移除 |
| 迁移期 | 从叶子页面开始 → 逐步向上 | 路由冲突 → 用子路径或 hash |
| 共存期 | 状态/事件总线隔离 | 用 CustomEvent 或 postMessage |
| 统一期 | 选定主框架 → 迁移剩余模块 | 优先选团队最熟的那个 |
最终建议(2026 年视角):
- 短期(3-6个月):页面级独立迁移 + 公共组件抽取
- 中期(6-18个月):引入微前端(Module Federation 优先)
- 长期:统一到一个框架(通常 React 生态更强,但 Vue 更友好)
重阳,你现在的项目是哪种情况?
- 纯静态 HTML,想整体转 Vue / React?
- 已经有 jQuery / Bootstrap,想局部现代化?
- 多团队、多框架并存的微前端?
- 具体卡在路由/样式隔离/状态共享?
告诉我更多细节,我可以给你更精确的目录结构、vite.config、迁移 checklist,甚至伪代码示例~