Laravel+Vite项目构建后manifest.json路径不匹配导致生产环境报错
我太懂这种本地跑起来顺风顺水,一构建上线就掉坑里的感受了!你遇到的这个问题核心就是Vite构建产物的manifest文件路径和Laravel默认的查找路径不匹配——明明构建成功了,文件却生在了public/build/.vite子目录里,而Laravel的Vite组件默认只会去public/build/根目录找manifest.json,可不就报找不到的错误嘛。咱们一步步来解决:
问题根源分析
看你的package.json里的构建命令是vite build && vite build --ssr,相当于串行执行了两次Vite构建:
- 第一次
vite build是客户端资源构建,会把manifest.json生成在public/build/目录下(符合Laravel的预期); - 第二次
vite build --ssr是SSR资源构建,它会默认把SSR相关的manifest生成在public/build/.vite/目录下,这就把第一次的正确路径给“打乱”了,最终Laravel去默认路径找的时候自然找不到文件。
解决方案
方案1:修复构建脚本,合并客户端与SSR构建(推荐)
Laravel官方的laravel-vite-plugin已经集成了SSR构建的支持,完全不需要分开执行两次构建命令。咱们直接优化脚本:
- 打开
package.json,把scripts部分改成这样:
"scripts": { "build": "vite build", "dev": "concurrently \"vite\" \"vite --ssr resources/js/ssr.js\"" }
- build命令:只保留
vite build就行,因为你已经在vite.config.js里配置了ssr: 'resources/js/ssr.js',插件会自动同时构建客户端资源和SSR产物,并且把manifest.json生成在public/build/的正确位置; - dev命令:用
concurrently并行启动两个服务(原来的串行写法vite && vite --ssr根本跑不起来第二个服务,你之前dev模式能工作估计是手动开了两个终端吧😅)。
- 重新执行构建:
npm run build
这时候去public/build/目录下看,manifest.json已经乖乖待在那了,Laravel自然能找到它,生产环境访问就不会报错了。
方案2:如果必须分开构建,统一Manifest输出路径
要是因为某些特殊需求你得保持两次构建的方式,那咱们就强制让SSR构建的manifest输出到正确路径:
修改vite.config.js的build配置,添加SSR相关的输出规则:
export default defineConfig({ build: { manifest: true, // 为SSR构建指定统一的输出目录和manifest配置 ssrManifest: true, outDir: 'public/build', }, // 其他现有配置(laravel插件、svelte插件、别名等)保持不变 });
然后把package.json的build命令改成:
"build": "vite build && vite build --ssr --outDir public/build"
这样两次构建都会把产物输出到public/build/目录,manifest.json也会在Laravel预期的位置。
方案3:让Laravel去错误路径找Manifest(不推荐,应急用)
如果上面两个方案都没法用,那咱们就“迁就”一下当前的构建结果,告诉Laravel去public/build/.vite/目录找文件:
- 先发布Laravel Vite的配置文件(如果还没发布过):
php artisan vendor:publish --tag=vite-config
- 打开
config/vite.php,找到manifest_path这一项,修改成:
'manifest_path' => public_path('build/.vite/manifest.json'),
保存后重新部署,Laravel就能找到正确的manifest文件了。不过这个方案只是临时应急,还是推荐用前两个方案从根源解决问题。
验证
不管用哪个方案,构建完成后先检查public/build/(或者你指定的路径)下是否存在manifest.json,然后访问生产环境的网站,那个恼人的ViteManifestNotFoundException应该就消失啦!
内容来源于stack exchange




