こんにちはjunです。最近よくLaravelの開発を行っていて、プロトタイプとかをherokuにあげるのですがLaravel mixのアセットが動かない(main.jsが404)でちょっと困ったので、今回はその対処法を書きたいと思います。
Laravelmixの説明を軽くするので、さっさと解決策みたいひとは「ビルドアセットをgitignoreしていた」から参照してください。なお使用環境は以下の通りです。
Laravel 6 PHP 7.4 Node.js 12.21(開発) Node.js 14.16(heroku)
Laravel MixはLaravelが公式に出している、JS・CSSのアセットコンパイラとモジュールバンドラです。resource
配下のjsやsassをコンパイルしたり、バンドルするwebpackの設定がすでにLaraveに最適化されています。webpackをほとんど触らずともvue、react、sass、そのほかjsライブラリをもちいた開発ができます。
resource 配下のアセットはLaravel Mixによってpublic配下に自動的に吐かれるようになっています。開発時にはnpm run watchをしていますが、よく見るとpublic配下に開発用ビルドしたアセットファイルが逐一置かれています。
大体のLaraveフロントエンドではこのMixを用いて開発していることが多いと思います。しかしherokuや本番環境にあげた時にちょっと問題がおきました。
Laravel Mixでフロントを構築して、ある程度バック含めて完成したのでherokuにデプロイしてみました。ビルドは普通に成功し、満を辞して目的の画面をみてもmain.js is not found
となってしましました。main.js
にはビルドしたvue.jsのプロジェクトがあるはずなのにと思い、サーバーに入ってpublic/js
配下をみてみたところ、何もありませんでした。
ビルドされたアセットはpublic配下に置かれますが、ファイル量が膨大だったり、開発モードと本番モードが混じる可能性があること、あとどうせコロコロ変わるのでバージョン管理から外そうと思い、public/jsとpublic/cssはバージョン管理から外していました。
herokuは基本的にgitを用いてデプロイします。管理対象外のファイルはもちろんherokuサーバー上にないので、アセットがあるはずもありません。であればherokuにデプロイした時にLaravel Mixを叩いて、ビルドすれば解決します。
HerokuではNODE_ENV
がproduction
(本番環境)で定義されていると、devDependencies
がプリーニングされてしまい、ビルドがうまく走りません。
インストールおよびビルドステップを実行した後、 Heroku はアプリケーションをデプロイする前に、devDependencies に宣言されているパッケージを取り除きます。
https://devcenter.heroku.com/ja/articles/nodejs-support#skip-pruning
インストールおよびビルドステップを実行した後、 Heroku はアプリケーションをデプロイする前に、devDependencies
に宣言されているパッケージを取り除きます。
対策としてはpackage.json
をいじってdependencies
に移動します。デフォルトでLaravel Mixはdevの方にインストールされます。それを移動してプッシュすればひとまずLaravel Mixのビルドがうまくいきます。
その2に加えて、今度はherokuデプロイの際にLaravel Mixのビルドスクリプトがキックされるように設定します。herokuはNode.jsのプロジェクトがあり、そのスクリプトにnpm run build
がある場合はそれを実行してくれます。
初期のpackage.json
のスクリプトはbuild
がないので、mixが実行されません。
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js"
},
ちょうどprodというのがあるのでbuildに変えてやりましょう。
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
"build": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js"
},
こうすればnpm run build
が npm run production
を実行して本番用のアセットを作ってくれます。これで解決です。
今回はいくつかのファイルをビルドする必要があり、デプロイ作業が自動で行われる状況でした。開発環境ではアセットがあるのに、本番だとなくなっているという場合は以下のことを考えましょう。
大体こうゆうときはビルドがうまくいっていないので、そこからチェックしていくといいです。ちなみに私が検索した時のワードは 「heroku laravel mix ビルド」 でした。それではまた。