Heroku执行npm run start无法识别concurrently命令该如何解决?
问题核心原因
你遇到的报错和部署失败本质是两个问题叠加导致的:
- 初始的127错误是依赖安装问题:
concurrently、json-server、@vue/cli-service这些包你都安装在了devDependencies下,而Heroku生产环境默认只会安装dependencies下的依赖,导致运行时找不到命令。 - 即使解决了依赖问题,你的启动方案也不符合Heroku和生产环境的规范:
- Heroku单个web dyno只会对外暴露一个端口,你同时启动json-server(默认3000端口)和vue-cli开发服务(默认8080端口),外网最多只能访问到一个服务
vue-cli-service serve是面向开发环境的热重载服务,性能极低,完全不适合生产环境使用
推荐可行方案(生产环境可用)
调整架构,把Vue前端编译为静态资源,用Express统一托管静态资源和代理json-server接口,单进程运行,完全适配Heroku的规则,步骤如下:
- 安装生产环境必需依赖
npm install express json-server --save
- 项目根目录新建入口文件
server.js,内容如下:
const express = require('express') const jsonServer = require('json-server') const path = require('path') const app = express() // 直接读取Heroku分配的端口,默认本地开发用8080 const PORT = process.env.PORT || 8080 // 托管Vue编译后的静态资源 app.use(express.static(path.join(__dirname, 'dist'))) // 所有/api前缀的请求转发给json-server处理,可自定义前缀 const jsonRouter = jsonServer.router('db.json') const jsonMiddlewares = jsonServer.defaults() app.use('/api', jsonMiddlewares, jsonRouter) // 其余所有请求返回Vue的index.html,支持前端路由history模式 app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')) }) app.listen(PORT, () => { console.log(`服务已启动,端口:${PORT}`) })
- 修改
package.json的scripts配置:
{ "scripts": { "start": "node server.js", "build": "vue-cli-service build", // Heroku部署完成后自动执行build命令编译Vue项目 "heroku-postbuild": "npm run build" } }
- 前端代码里所有调用json-server的接口地址都加上
/api前缀即可,比如原来请求http://localhost:3000/table1改成请求/api/table1。
注意事项
- Heroku的文件系统是临时性的,每次dyno重启、重新部署都会重置所有本地写入的文件,你存在
db.json里的修改内容会丢失,如果需要持久化存储数据,需要替换为Heroku提供的PostgreSQL等数据库服务。 - 不建议继续使用concurrently多进程启动的方案,除了端口冲突问题,多进程会额外消耗dyno的资源,也不符合Node.js生产环境的部署规范。
内容的提问来源于stack exchange,提问作者user17176542
相关产品推荐
相关产品推荐

