laravel5.6でjQueryを使おうとすると、Uncaught ReferenceError: $ is not definedが出る時の対処方法


追記:
コンメトで正攻法の解決方法をアドバイスいただきました。
当記事はやっつけの解決策なので、みんなはマネしちゃダメだぞ☆


laravel5.6 をインストールして jQuery を使おうとしたら、jquery.js を読み込んでいるはずなのに使えなくてハマったのでメモ。

状況

laravel5.6 を普通にインストールして、
$ npm install
$ npm run dev
した状態からスタート。

デフォルトで jQuery が読み込まれているようなので、
blade.php ファイルに jQuery のコードを書いたらエラーが発生して動かない。

javascript
$(function(){
  // ここにプログラムを記述
});

これだけなのに、以下のエラー。

jsエラー
Uncaught ReferenceError: $ is not defined

どうやら jQuery が読み込まれていないというエラーのよう。

原因

あまり詳しくはないけど、どうやら laravel5.6 では(5.5あたりから?) vue がデフォルトになっているようなので、もしかしたら jQuery なんかも vue 方式で書かないと行けないのかもしれない。

そんな急に vue を覚えろと言われても、すぐに実用レベルで使えるかどうかもわからないので、まずは旧来の書き方で良いから動かしたい。(そんなんだから二流プログラマーなんだよと言われそうだけど)

調べていたら、こいつが怪しい。

layouts/app.blade.php
    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

defer ってなんだ?

<script> タグに async / defer を付けた場合のタイミング
https://qiita.com/phanect/items/82c85ea4b8f9c373d684

どうやら、 defer を付けると処理の実行を遅延させることができるらしい。

つまり、blade内に jQuery のプログラムを書いても、元になる jquery.js が遅延されて後から実行されるので、 jquery.js が読み込まれていないというエラーが発生しているようだ。

結論

とりあえず、 jQuery をベタに書いて動かしたいなら、 defer を削除すれば動く。

app.blade.php
- <script src="{{ asset('js/app.js') }}" defer></script>
+ <script src="{{ asset('js/app.js') }}"></script>

最初に書いた vue は関係ありそうな気がしたけど関係なさそう。
でも今回は使わないので、 assets/js/app.js から vue 関連のところは消してコンパイルしておきました。

app.js に重い処理などを書くようになると、 defer を外した影響が出てくる可能性があるので、ちゃんと良い書き方覚えないとと思いながら、今日も妥協のコーディング。