Next.js电商项目部署Heroku后仅显服务端数据,无页面渲染
Next.js + Node.js 部署Heroku页面不渲染问题排查与解决
问题核心现象
- 本地运行时功能正常,Heroku访问首页仅返回接口JSON数据,无前端UI渲染
- 访问/login等无数据路由时显示"Not Found",Heroku日志报错
Error: ENOENT: no such file or directory, stat '/app/client/build/index.html' - Heroku构建日志显示成功,但无法加载前端页面文件
排查与解决步骤
1. 修正Next.js构建产物路径
Next.js默认执行next build后生成的是.next目录,而非build目录,这是导致找不到页面文件的核心原因。提供两种解决方案:
方案一:改用Next.js官方生产服务启动
修改根目录package.json的脚本,直接让Next.js处理前端路由,Node服务可迁移至Next.js的API Routes(推荐):
// 根目录package.json "scripts": { "start": "cd client && npm start", "heroku-postbuild": "cd client && npm install && npm run build" }, "engines": { "node": "18.9.1" }
同时可移除server.js中关于静态文件和catch-all路由的代码,让Next.js自主管理前端路由。
方案二:配置Next.js导出静态文件到build目录
修改client/package.json的构建脚本,添加静态导出命令:
// client/package.json "scripts": { "dev": "next dev", "build": "next build && next export -o build", "start": "next start -p $PORT", "lint": "next lint" }
并在client/next.config.js中添加导出配置(Next.js 13+):
// client/next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { output: 'export', // 其他项目配置... } module.exports = nextConfig
执行构建后会生成client/build目录,匹配server.js中指定的文件路径。
2. 调整服务端路由优先级
若保留Node.js服务作为主入口,需确保API接口路由在静态文件服务和catch-all路由之前定义,避免请求优先命中API返回JSON:
// server.js // 先定义所有API接口 app.get('/api/products', (req, res) => { /* 商品接口逻辑 */ }); // 再配置静态文件和前端路由 app.use(express.static(path.join(__dirname, "client", "build"))); if (process.env.NODE_ENV === "production" || process.env.NODE_ENV === "staging") { app.get("*", (req, res) => { res.sendFile(path.join(__dirname, "client", "build", "index.html")); }); }
3. 验证Heroku构建产物
通过Heroku CLI确认client/build目录是否存在:
heroku run ls client/build -a your-app-name
若提示目录不存在,简化根目录heroku-postbuild脚本(移除--only=dev避免跳过生产依赖安装):
"heroku-postbuild": "cd client && npm install && npm run build"
4. 检查Git忽略规则
- 若采用方案二导出静态文件,确保
client/.gitignore中未添加build/规则; - 若采用方案一,
client/.gitignore可保留.next/,依赖Heroku重新构建。
5. 确认NODE_ENV环境变量
Heroku默认设置NODE_ENV=production,可通过以下命令验证:
heroku config:get NODE_ENV -a your-app-name
若未设置,手动添加:
heroku config:set NODE_ENV=production -a your-app-name
内容的提问来源于stack exchange,提问作者user20936494
相关产品推荐
相关产品推荐

