如何基于单个Node.js服务器部署两个Create React App创建的React应用
用单个Node.js服务器部署两个独立React应用的方案
嘿,这问题我之前帮朋友搞定过,核心就是让Node服务器根据请求路径分发到对应的React构建产物,同时配合React Router的basename配置解决客户端路由冲突,一步步来:
第一步:准备两个React应用的构建文件
首先,分别对两个create-react-app项目执行构建,注意要指定资源路径前缀避免冲突:
- 对于第一个应用(比如叫
app1),在项目根目录运行:
构建完成后,把生成的PUBLIC_URL=/app1 npm run buildbuild文件夹重命名为app1-build,复制到你的Node服务器项目的public目录下。 - 第二个应用(
app2)同理:
重命名为PUBLIC_URL=/app2 npm run buildapp2-build,也放到Node服务器的public目录里。
第二步:搭建Node.js Express服务器
我用Express做示例,这是最常用的Node服务器框架:
- 先初始化Node项目并安装依赖:
mkdir react-multi-app-server && cd react-multi-app-server npm init -y npm install express path - 创建
server.js文件,写入以下代码:const express = require('express'); const path = require('path'); const app = express(); const PORT = process.env.PORT || 3000; // 托管两个应用的静态资源 app.use('/app1', express.static(path.join(__dirname, 'public', 'app1-build'))); app.use('/app2', express.static(path.join(__dirname, 'public', 'app2-build'))); // 处理App1的所有路由请求(包括React Router的客户端路由) app.get('/app1/*', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'app1-build', 'index.html')); }); // 处理App2的所有路由请求 app.get('/app2/*', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'app2-build', 'index.html')); }); // 默认根路径跳转(可选,比如跳转到app1) app.get('/', (req, res) => { res.redirect('/app1'); }); app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });
第三步:配置React应用的Router
每个应用的React Router必须设置basename,不然客户端路由会和服务器路径冲突:
- 在
app1的路由配置里:import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; function App() { return ( <Router basename="/app1"> {/* 必须添加basename */} <Routes> <Route path="/" element={<Home />} /> <Route path="/dashboard" element={<Dashboard />} /> {/* 其他路由... */} <Route path="/go-to-app2" element={<a href="/app2">跳转到应用2</a>} /> </Routes> </Router> ); } app2同理,设置basename="/app2",并添加跳回app1的链接:<a href="/app1">回到应用1</a>
关键注意点
- 跨应用跳转必须用原生
<a>标签,不能用React Router的<Link>——因为<Link>只会在当前应用的客户端路由内跳转,跨应用需要触发服务器的路径分发。 - 一定要设置
PUBLIC_URL和basename,不然静态资源会找不到,客户端路由也会出错。 - 如果你的React应用用的是
HashRouter,basename配置可以简化,但一般推荐用BrowserRouter配合服务器配置,URL更友好。
最后启动Node服务器:
node server.js
访问http://localhost:3000/app1就能看到第一个应用,点击跳转链接会切换到/app2,两个应用的路由都能正常工作,刷新页面也不会出现404啦!
内容的提问来源于stack exchange,提问作者Mendes
相关产品推荐
相关产品推荐

