如何使用ExpressJS将用户路由到多个独立的React单页应用
实现方案
你不需要强制拆分两个独立create-react-app项目,两种实现方案可根据你的业务场景选择:
方案一:单项目多入口打包(更推荐,适合有公共组件/工具复用的场景)
不用受限于create-react-app的默认单入口配置,改用Vite或自定义webpack配置即可实现多独立React应用打包,配置成本很低:
1. 项目结构示例
项目根目录 ├── server/ # Express服务代码 │ └── index.js ├── src/ │ ├── common/ # 公共组件、工具函数 │ ├── entry-root/ # 对应/路径的React应用 │ │ ├── index.html │ │ ├── main.jsx │ │ └── App.jsx │ └── entry-app/ # 对应/app路径的React应用 │ ├── index.html │ ├── main.jsx │ └── App.jsx └── vite.config.js
2. 多入口打包配置(以Vite为例)
// vite.config.js import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], build: { rollupOptions: { input: { root: './src/entry-root/index.html', app: './src/entry-app/index.html' } } } })
执行npm run build后,打包产物会统一输出到dist目录,两个入口的资源自动区分。
3. Express路由配置
把SSR路由放在最前面,之后配置React应用的路由即可:
// server/index.js const express = require('express') const path = require('path') const app = express() // 优先走服务端渲染的路由 app.get('/about', (req, res) => { res.render('about.ejs') }) app.get('/news', (req, res) => { res.render('news.ejs') }) // 其他SSR路由同理 // 配置React应用路由 app.get('/', (req, res) => { res.sendFile(path.join(__dirname, '../dist/entry-root/index.html')) }) // 匹配/app以及/app下的所有子路由 app.get('/app*', (req, res) => { res.sendFile(path.join(__dirname, '../dist/entry-app/index.html')) }) // 托管静态资源 app.use(express.static(path.join(__dirname, '../dist'))) // 404兜底 app.use((req, res) => { res.status(404).render('404.ejs') }) app.listen(3000, () => console.log('服务启动成功'))
这种方案下你可以正常通过npm安装第三方React组件,两个应用可以复用公共逻辑,维护成本更低。
方案二:两个独立create-react-app项目(适合业务完全隔离的场景)
如果两个React应用的业务完全不相关、后续维护也由不同团队负责,可以选择拆分项目:
- 在项目根目录分别新建
react-home、react-app两个文件夹,分别用create-react-app初始化 - 修改
react-home/package.json的homepage字段为"/",修改react-app/package.json的homepage字段为"/app" - 两个项目分别执行
npm run build打包,将打包后的build目录分别存放到Express服务的静态资源目录下的对应位置 - Express路由配置逻辑和方案一一致,只需要修改
sendFile的路径对应两个build目录的index.html即可
注意事项
如果单个React应用内部需要子路由,可以在应用内单独引入React Router配置,不需要影响全站其他路由;Express的/app*通配符路由要放在所有SSR路由之后,避免拦截到需要服务端渲染的路径。
内容的提问来源于stack exchange,提问作者Rohan Hussain
相关产品推荐
相关产品推荐

