はじめに
Rails8×デフォルトのImportmapでaxiosを使う際にハマったので解決策をのこしておきます
やりたいこと
- ImportmapでAxiosを使いたい
やったこと
- CLI上で、
./bin/importmap pin axios
を実行 - 以下のように
config/importmap.rb
に記述される
pin "axios" # @1.7.9
pin "#lib/adapters/http.js", to: "#lib--adapters--http.js.js" # @1.7.9
pin "#lib/platform/node/classes/FormData.js", to: "#lib--platform--node--classes--FormData.js.js" # @1.7.9
pin "#lib/platform/node/index.js", to: "#lib--platform--node--index.js.js" # @1.7.9
デバッグ過程
エラー1:モジュールの解決ができない
Uncaught TypeError: Failed to resolve module specifier "#lib/platform/node/classes/FormData.js"
- 原因
- Node.js用のモジュールを読み込もうとしていたため
- 解決策
- CDNを直接読み込むように修正
pin "axios", to: "https://cdn.jsdelivr.net/npm/axios@1.7.9/dist/axios.min.js"
# 上記のみ記載する
エラー2: 構文エラー
Uncaught SyntaxError: The requested module 'axios' does not provide an export named 'default'
- 原因
- importの書き方の誤り
- CDNで使う場合のimport文の形式になっていなかった
- 解決策
- CDN版は自動的にグローバルオブジェクトになるらしい
// 変更前
import axios from 'axios'
// 変更後
import 'axios'
エラー3: getが未定義として認識される
Cannot read properties of undefined (reading 'get')
- 原因
- window.axios として明示的にグローバル化しようとしていた部分が不要
- 解決策
// 変更前
window.axios = AxiosModule.default
// 変更後
// window.axiosの設定は不要
// 直接axiosとして使用可能
理解できたこと
- ImportmapはWebpackのようにバンドルしないので、Rails6以前と比較して記述方法が異なる
- Webpackの場合はNode.jsモジュールをブラウザ互換のコードに変換(トランスパイル)して使用する
- なので
yarn add hogehoge
でモジュールをインストールする必要がある
- なので
- Importmapはブラウザのみで動かしているため、Railsプロジェクト内のファイルシステムにアクセスできない
- そのためCDNで依存先を指定する必要がある
おわりに
そもそもNode.jsやCDNについて基本的な理解が足りていない感覚がすごいので、勉強します。
参考