RailsのbootstrapでUncaught TypeError: Cannot read property 'fn' of undefined at setTransitionEndSupport エラーが発生する 他。
ローカルで動くHTML,CSS,JavascriptをRailsで動かそうとしたらJSが大量にエラーを吐いていました。ChromeのF12でConsleを確認すると いろいろとエラーが出てますね....。でてきたエラーは
- Uncaught TypeError: Cannot read property 'fn' of undefined at setTransitionEndSupport - bootstrap.min.js
- Uncaught ReferenceError: jQuery is not defined - 他js
これらのエラーは同じ原因によって発生しているようです。
原因 jQueryが読み込まれる順番が遅い
RailsではAssetspipelineによってjsやcssが一つのファイルとして纏められます。
javascriptをまとめる順番はassets/javascript/application.jsで明示することができますが、デフォルトでは以下のようになっています。
// This is a manifest file that'll be compiled into application.js, which will include all the files // listed below. // // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's // vendor/assets/javascripts directory can be referenced here using a relative path. // // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // compiled file. JavaScript code in this file should be added after the last require_* statement. // // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details // about supported directives. // //= require rails-ujs //= require activestorage //= require turbolinks //= require_tree .
最後の//= require_tree .
でassets/javascript内のjsをファイル名の順番で読み込んでいるようです。
ここを見るとbootstrapはjQueryとPopper.jsを先に読み込む必要があります。しかし//= require_tree .
は名前順に読み込むので、名前がそのままだと
- bootstrap.js
- jQuery.js
- Popper.js
という順番で読み込まれてしまいます。どうやらこれのせいで「Uncaught TypeError: Cannot read property 'fn' of undefined at setTransitionEndSupport 」エラーは発生しているようです。以下のリンクでも同様のエラーが発生していたようです。
他のJSの「Uncaught ReferenceError: jQuery is not defined」エラーもjQueryを前提としているのにjQueryより先に読み込まれていることによるエラーのようです。
これを解消するにはapplication.jsで読み込む順番を明示してあげる必要があります。
解消方法
application.jsのrequire部分に以下のように書き加えます。
前略 // //= require rails-ujs //= require activestorage //= require turbolinks //= require jquery-min //= require popper.min //= require_tree .
//= require_tree .
の前に//= require jquery-min //= require popper.min
と書くことによってjQuery,popper.jsを読み込んだ後に他のjsファイルを読み込んでくれます。このように他のjsの前提となっているファイルは//= require_tree .
の前に書くようにすればいいですね。もしくは全てのjsを順番を明示して読み込むのもアリだと思います。