Node.js部署Heroku时postinstall执行cp命令后运行时文件不存在
问题原因及解决方案
注:你将生成的资源文件加入.gitignore是合理操作,不会导致该问题,无需修改这部分配置。
核心常见原因
- 拷贝命令生成的目录结构和预期不符,导致资源引用路径错误
- 依赖放置位置错误,构建阶段无法找到对应资源包
- 大小写不匹配,本地(Windows/macOS)默认大小写不敏感可正常访问,Heroku Linux环境大小写敏感返回404
- 静态资源路由配置优先级低于其他业务路由,导致静态请求被拦截
具体排查修复步骤
- 修正拷贝路径或资源引用路径
你当前使用的拷贝命令:cp -r ./node_modules/materialize-css/dist/ ./www/
执行完成后会生成www/dist/css/、www/dist/js/的目录结构,如果你HTML中引用路径写的是/css/materialize.min.css就会出现404。
可选修复方案二选一:
- 修改引用路径为
/dist/css/materialize.min.css、/dist/js/materialize.min.js - 修改拷贝命令,直接把dist目录下的内容复制到www根目录:
cp -r ./node_modules/materialize-css/dist/* ./www/
确认依赖放置位置
检查package.json中materialize-css是否放在dependencies字段下,不要放在devDependencies中,避免Heroku构建阶段裁剪开发依赖时提前移除包,导致拷贝失败。排查大小写匹配问题
核对资源引用路径的大小写和实际文件的大小写完全一致,比如路径中写的Materialize.min.css和实际文件名materialize.min.css会被Linux系统判定为不同文件。添加构建日志确认拷贝结果
修改package.json的postinstall脚本,添加目录打印逻辑,部署后查看Heroku构建日志确认文件生成位置是否符合预期:
{ "scripts": { "postinstall": "cp -r ./node_modules/materialize-css/dist/ ./www/ && ls -R ./www" } }
- 调整静态资源路由优先级
确保express的静态资源配置代码放在所有业务路由定义之前,避免动态路由拦截静态资源请求:
// 静态资源配置放在最前面 app.use(express.static(path.join(process.cwd(), 'www'))) // 其他业务路由放在后面 app.get('/api/xxx', (req, res) => { // 业务逻辑 })
内容的提问来源于stack exchange,提问作者Christoph Herrmann
相关产品推荐
相关产品推荐

