Rails 7 でファイルごとに JavaScript を分けて使えるようにする
Rails 7 では node.js や yarn を使用せずに JS のパッケージ管理をする方向に動いています。
そこで代わりに使用するのが importmap です。
詳しくは以下を参考にさせていただきました。
今回はこれまでの Rails で使用していた assets.precompile を使用せずに、それぞれのファイルごとに JavaScript ファイルを紐付ける方法を記します。
概要
目的
- Rails 7 で importmap を使用して JavaScript を使用する
- ファイル個別に JavaScript を効かせる
前提
- yarn などは使用せず importmap を使用する
手順
importmap でファイル毎に javaScript を使用できるようにする
まずは前提として Rails 7 では環境構築した段階で以下ファイルから JS を使用することが可能です。
console.log("JS 使えてるねん!");
個別にファイルを作ってみる。。。
+ console.log("JS 使えてまっか?")
↑↑ 今回は View のtop/index.html.erb
というファイルに JS を適用させたいので、ディレクトリ名とファイル名を揃えました。
もちろんこれだけではtop/index.html.erb
側にはこのファイルの JS は適用されていません。
ここで使用するのが「importmap」です。
importmap のファイルに以下のよう「top/index」をピン留めします。
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
+ pin "top/index"
ピン留めをすることで HTML の Head にあるimports
に以下のように追加されます。
あとはこれをtop/index
のファイルで呼び出すように書けば機能するはずです。
以下の通りjavascript_importmap_tags
という箇所で、importmap を呼び出しています。
この下にyield(:js)
を追記します。
<%= javascript_importmap_tags %>
+ <%= yield(:js) %>
そして呼び出し元であるファイルに以下を追記します。
+ <% content_for :js do %>
+ <%= javascript_import_module_tag "top/index" %>
+ <% end %>
すると、無事に console.log が表示されました!
上記ではtop/index
という JS ファイルを指定しているので、それが反映されます。
なので、他のページではここを変更してやればよいわけです。
また、top ディレクトリ以下のファイルに同じ JS を適用させたい時は inportmap を以下のように編集してやります。
- pin "top/index"
+ pin_all_from "app/javascript/top", under: "top"
合わせて以下も変更
<% content_for :js do %>
- <%= javascript_import_module_tag "top/index" %>
+ <%= javascript_import_module_tag "top" %>
<% end %>
これでtop/show
などでも同じ JS が適用されます!
まとめ
ファイル個別に適用する場合
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
+ pin "top/index"
<%= javascript_importmap_tags %>
+ <%= yield(:js) %>
+ <% content_for :js do %>
+ <%= javascript_import_module_tag "top/index" %>
+ <% end %>
ディレクトリ全体に適用する場合
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
+ pin_all_from "app/javascript/top", under: "top"
<%= javascript_importmap_tags %>
+ <%= yield(:js) %>
+ <% content_for :js do %>
+ <%= javascript_import_module_tag "top" %>
+ <% end %>
お疲れ様でした◎
Discussion