如何在生产环境通过Node/Express服务器部署Next.js构建产物?
在Express服务器中部署Next.js生产构建产物的方案
Next.js的产物结构和纯SPA(比如Vite打包的React)完全不同,不能直接用express.static或者返回单一index.html的方式处理。下面是生产环境中通过Express集成Next.js的标准做法:
核心思路
Next.js本身内置Node.js服务器,但也支持自定义Express服务器接管请求路由,同时复用Next.js的构建产物。不需要手动处理.next目录内的文件,而是通过Next.js提供的next模块加载构建产物,自动处理SSR、静态资源、路由等逻辑。
具体步骤
1. 安装依赖
确保项目已安装next、react、react-dom,同时保留express:
npm install next react react-dom express
2. 配置Next.js(可选但推荐)
在next.config.js中开启standalone输出(Next.js 12+支持),生成包含所有依赖的独立运行目录,更适合部署:
/** @type {import('next').NextConfig} */ const nextConfig = { output: 'standalone', } module.exports = nextConfig
3. 编写Express集成代码
创建server.js文件,用Next.js的createServer方法完成集成:
const express = require('express'); const next = require('next'); const dev = process.env.NODE_ENV !== 'production'; const app = next({ dev }); const handle = app.getRequestHandler(); // 初始化Next.js,加载构建产物 app.prepare().then(() => { const server = express(); // 这里可以添加你的自定义Express路由 server.get('/api/custom', (req, res) => { res.json({ data: '来自Express自定义接口的响应' }); }); // 让Next.js处理所有其他请求(SSR页面、静态资源、Next.js API路由等) server.all('*', (req, res) => { return handle(req, res); }); const PORT = process.env.PORT || 3000; server.listen(PORT, (err) => { if (err) throw err; console.log(`服务器运行在 http://localhost:${PORT}`); }); });
4. 调整构建与启动脚本
在package.json中修改脚本,先构建Next.js再启动Express服务器:
{ "scripts": { "build": "next build", "start": "NODE_ENV=production node server.js", "heroku-postbuild": "next build" } }
5. Heroku部署注意事项
- Heroku会自动执行
start脚本,heroku-postbuild脚本用于在部署阶段完成Next.js构建 - 确保
.gitignore不忽略.next/standalone和.next/static目录(如果用standalone输出),或者不忽略整个.next目录
不要直接托管.next目录的原因
.next目录是Next.js的内部编译产物,包含缓存、中间编译文件等,直接用express.static托管会导致SSR失效、路由错误、资源加载失败等问题。必须通过Next.js提供的handle函数处理请求,它会自动区分静态资源、SSR页面、API路由等场景。
内容的提问来源于stack exchange,提问作者Nirav Venkatesan
相关产品推荐
相关产品推荐

