 
  こんにちは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 ビルド」 でした。それではまた。