[bootstrap5]本番環境でドロップダウンが動かない問題（TypeError: t.createPopper is not a function）

## 目的
Rails７でwebアプリを開発している際に開発環境でbootstrap5を使用してました。

本番環境にデプロイしてみるとドロップダウンの機能が動かなかったので
その問題解決時に得た情報を備忘録として残します。

Rails7にbootstrap5を導入する記事がネット上に多くありましたが
どれも自分の環境では動かなかったので自分と同じように困っている方の役に立てれば幸いです。

## 開発環境
Rails　7.0.4.3
ruby 3.1.4
bootstrap 5.3.3

## 動かなかった時の状態
前に[こちら](https://qiita.com/ruby_of_pokemon/items/2a5452bcd5db0d12a230)の記事でPopper.jsのエラー解決方法を紹介したのですが、開発環境では問題なく動いていました。
しかし、いざ本番環境にデプロイするとbootstrapのドロップダウンが動きませんでした。

ちなみに本番環境でドロップダウンを押した際にブラウザのコンソールで出たエラーがこちらになります。
<br>

![スクリーンショット 2024-06-25 17.55.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2049725/08fb99fa-26a9-b5f2-34df-ac8e6b9a111c.png)
<br>
ブラウザで表示されるソースコードを確認すると、bootstrap.jsの一部の処理でエラーが起きていました。

なんとなくまたPopper.jsがうまく読み込まれていないと思ったのですが
一応ソースコードを確認しました。

その時のソースコードが下になります。
<br>

```bootstrap.349420...(プリコンパイル後の数列).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`が定義されている場所が１行目にありました。
<br>

```bootstrap.349420...(プリコンパイル後の数列).js
import*as t from "@popperjs/core";
```
<br>
あれ、この`@popperjs/core`見たことある。
<br>

```importmap.rb
pin "@popperjs/core", to: "https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.11.8/umd/popper.min.js"
```
<br>

importmap.rbでPopper.jsをpin留めしたコードを思い出しました。

これでPopper.jsがうまく読み込まれていないんだなという確信に至り
前の記事を参考にcdnのリンクを色々変えましたが、結果は全く同じエラーが出てしまうという。。。

途方に暮れました☆

おしまい

<br>
<br>
<br>
まぁこれで終われる訳ないのですが、色々記事を探していたら解決できたので次項で説明します。

## bootstrapの再導入
bootstrapの記事を色々探しても同じようなPopper.jsの導入方法が書いてあるので、途方に暮れていたのですが
ふとbootstrap公式のドロップダウンのページを見るとこんなことが書かれていました。

>ドロップダウンはサードパーティのライブラリであるPopper.jsを使って構築されており、動的なポジショニングとビューポート検出を提供しています。必ずBootstrapのJavaScriptの前にpopper.min.jsをインクルードするか、Popper.jsを含むbootstrap.bundle.min.js / bootstrap.bundle.jsを使用してください。Popper.jsは動的な配置は必要ないので、ナビゲーションバーのドロップダウンの配置には使いませんが。

[bootstrap5公式](https://getbootstrap.jp/docs/5.3/components/dropdowns/)より引用

注目してほしいのは以下の内容です。

`Popper.jsを含むbootstrap.bundle.min.js / bootstrap.bundle.jsを使用してください。`

これが本当だとしたらわざわざ`importmap.rb`にPopper.jsを定義しなくていいのでは？
と思いました。

しかし、この`bootstrap.bundle.min.js / bootstrap.bundle.js`はどういうふうに読み込むの？

と疑問に思いましたが、[cdnjs](https://cdnjs.com/)というサイトでbootstrapと検索すれば
`bootstrap.bundle.min.js / bootstrap.bundle.js`のCDNが出てきました。

今回は`bootstrap.bundle.min.js`を採用して、以下のファイルを変更しました。
(不要なところは省略しています)
<br>

```importmap.rb
pin "bootstrap", to: "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.bundle.min.js" # @5.3.3
```

```application.js
import "bootstrap"
```

```assets.rb
#本番環境のプリコンパイルに指定するファイル名も変更
Rails.application.config.assets.precompile += %w( 
  bootstrap.bundle.min.js
)
```
<br>
Popperに関する定義や読み込みを削除し
bootstrapの記述を上記のように変更したら本番環境でも無事動きました。


Popper.jsが開発環境では読み込まれて、本番環境では読み込まれない理由につきましては調査中です。
新しい情報があれば記事を更新します。

また補足説明や間違いなどあればコメント欄に書いていただけると非常に嬉しいです。
<br>
今回の教訓：外部のモジュールやライブラリの導入は公式リファレンス見よう