目的
Rails7でwebアプリを開発している際に開発環境でbootstrap5を使用してました。
本番環境にデプロイしてみるとドロップダウンの機能が動かなかったので
その問題解決時に得た情報を備忘録として残します。
Rails7にbootstrap5を導入する記事がネット上に多くありましたが
どれも自分の環境では動かなかったので自分と同じように困っている方の役に立てれば幸いです。
開発環境
Rails 7.0.4.3
ruby 3.1.4
bootstrap 5.3.3
動かなかった時の状態
前にこちらの記事でPopper.jsのエラー解決方法を紹介したのですが、開発環境では問題なく動いていました。
しかし、いざ本番環境にデプロイするとbootstrapのドロップダウンが動きませんでした。
ちなみに本番環境でドロップダウンを押した際にブラウザのコンソールで出たエラーがこちらになります。
ブラウザで表示されるソースコードを確認すると、bootstrap.jsの一部の処理でエラーが起きていました。
なんとなくまたPopper.jsがうまく読み込まれていないと思ったのですが
一応ソースコードを確認しました。
その時のソースコードが下になります。
_createPopper() {
if (typeof t === "undefined")
throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");
let e = this._element;
this._config.reference === "parent" ? e = this._parent : isElement(this._config.reference) ? e = getElement(this._config.reference) : typeof this._config.reference === "object" && (e = this._config.reference);
const s = this._getPopperConfig();
this._popper = t.createPopper(e, this._menu, s) ←ここでエラーが起きていた。
}
率直な感想は意味わからん
でした
ここだけ見ても全然意味がわからないのですが
とりあえず、t
という変数に対してcreatePopper
メソッドがうまく呼び出されていないのか(エラー文に書いてある通り)
じゃあt
ってなんだろー
って思っていたらt
が定義されている場所が1行目にありました。
import*as t from "@popperjs/core";
あれ、この`@popperjs/core`見たことある。
pin "@popperjs/core", to: "https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.11.8/umd/popper.min.js"
importmap.rbでPopper.jsをpin留めしたコードを思い出しました。
これでPopper.jsがうまく読み込まれていないんだなという確信に至り
前の記事を参考にcdnのリンクを色々変えましたが、結果は全く同じエラーが出てしまうという。。。
途方に暮れました☆
おしまい
まぁこれで終われる訳ないのですが、色々記事を探していたら解決できたので次項で説明します。
bootstrapの再導入
bootstrapの記事を色々探しても同じようなPopper.jsの導入方法が書いてあるので、途方に暮れていたのですが
ふとbootstrap公式のドロップダウンのページを見るとこんなことが書かれていました。
ドロップダウンはサードパーティのライブラリであるPopper.jsを使って構築されており、動的なポジショニングとビューポート検出を提供しています。必ずBootstrapのJavaScriptの前にpopper.min.jsをインクルードするか、Popper.jsを含むbootstrap.bundle.min.js / bootstrap.bundle.jsを使用してください。Popper.jsは動的な配置は必要ないので、ナビゲーションバーのドロップダウンの配置には使いませんが。
bootstrap5公式より引用
注目してほしいのは以下の内容です。
Popper.jsを含むbootstrap.bundle.min.js / bootstrap.bundle.jsを使用してください。
これが本当だとしたらわざわざimportmap.rb
にPopper.jsを定義しなくていいのでは?
と思いました。
しかし、このbootstrap.bundle.min.js / bootstrap.bundle.js
はどういうふうに読み込むの?
と疑問に思いましたが、cdnjsというサイトでbootstrapと検索すれば
bootstrap.bundle.min.js / bootstrap.bundle.js
のCDNが出てきました。
今回はbootstrap.bundle.min.js
を採用して、以下のファイルを変更しました。
(不要なところは省略しています)
pin "bootstrap", to: "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.bundle.min.js" # @5.3.3
import "bootstrap"
#本番環境のプリコンパイルに指定するファイル名も変更
Rails.application.config.assets.precompile += %w(
bootstrap.bundle.min.js
)
Popperに関する定義や読み込みを削除し bootstrapの記述を上記のように変更したら本番環境でも無事動きました。
Popper.jsが開発環境では読み込まれて、本番環境では読み込まれない理由につきましては調査中です。
新しい情報があれば記事を更新します。
また補足説明や間違いなどあればコメント欄に書いていただけると非常に嬉しいです。
今回の教訓:外部のモジュールやライブラリの導入は公式リファレンス見よう