「RailsでちょっとしたJavaScriptライブラリを使いたいだけなのに、Webpackやnpmまわりの設定でつまずいた」——そんな経験はありませんか?Rails 7以降は importmap が標準になり、npm・Yarn・node_modules なしで JavaScript ライブラリを導入できるようになりました。この記事では、セレクトボックスを高機能にする slim-select を例に、importmap と Stimulus を組み合わせてライブラリを動かすまでの手順を解説します。Rails 8 でも同じ流れで動きます。
全体の流れ
先に結論から。やることは大きく4ステップです。
./bin/importmap pinでライブラリを追加する(config/importmap.rb に登録される)- Stimulus コントローラで
importして使う - view で
data-controllerを指定して紐付ける - 必要なら CSS を別途読み込む(importmap は JS 用なので CSS は対象外)
ポイントは、importmap-rails 2.0 以降は pin したパッケージが デフォルトで vendor/javascript/ にダウンロードされるようになったことです。以前のように毎回 CDN を叩くのではなく、ファイルを自分のアプリに取り込んで配信するので、オフラインでも動きバージョンも固定できます。
前提
- Rails 7 または Rails 8 で
rails newしている(importmap がデフォルト) - Stimulus(@hotwired/stimulus)が入っている
Rails のセットアップ自体がまだの方は、macOSにRuby on Railsをインストールもあわせてどうぞ。
①importmapでライブラリをpinする
ライブラリを追加するには、次のコマンドを実行します。
$ ./bin/importmap pin slim-select
Pinning "slim-select" to vendor/javascript/slim-select.js via download from https://ga.jspm.io/npm:slim-select@4.0.4/dist/slimselect.es.js実行すると、パッケージが vendor/javascript/ にダウンロードされ、config/importmap.rb に次の1行が追記されます。
# Pin npm packages by running ./bin/importmap
pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin_all_from "app/javascript/controllers", under: "controllers"
pin "slim-select" # 追加される(vendor/javascript/slim-select.js を指す)
CDN から直接読み込みたい場合は --from を付けて ./bin/importmap pin slim-select --from jsdelivr のように指定もできますが、基本はダウンロードして Git 管理下に置く方法がおすすめです。バージョンが固定され、外部 CDN の障害に左右されずに済みます。
②Stimulusコントローラで読み込む
pin したライブラリは、Stimulus コントローラの中で import して使います。slim-select という名前でそのまま import できるのが importmap の便利なところです。
import { Controller } from "@hotwired/stimulus"
import SlimSelect from "slim-select"
export default class extends Controller {
connect() {
this.select = new SlimSelect({
select: this.element,
})
}
disconnect() {
this.select.destroy()
}
}ファイル名が slim_select_controller.js なので、Stimulus 上の識別子(identifier)は slim-select になります(アンダースコアがハイフンに変換されます)。この名前が、次の view で指定する data-controller の値と一致している必要があります。ここがズレると「何も起きない」というハマりの定番です。
③viewでコントローラを紐付ける
対象のセレクトボックスに data-controller を指定します。②の identifier に合わせて slim-select と書きます。
<%= form.select :category, ["ruby", "php"], { include_blank: true }, data: { controller: "slim-select" } %>これで、このセレクトボックスが表示されたときに Stimulus の connect() が呼ばれ、slim-select が適用されます。
④CSSを読み込む
slim-select は見た目を整えるための CSS が必要です。importmap は JavaScript 専用なので、CSS は別途読み込みます。手軽なのは CDN からの読み込みです。
@import url("https://cdn.jsdelivr.net/npm/slim-select@4/dist/slimselect.css");CSS も外部に依存させたくない場合は、上記 URL のファイルをダウンロードして app/assets/stylesheets/ に置き、*= require slimselect で読み込む方法もあります。
よくあるハマりどころ
- コントローラ名と
data-controllerの値が一致していない:slim_select_controller.jsならdata-controller="slim-select"。アンダースコア→ハイフンの変換を忘れがちです。 - CSS を読み込んでいない:JS だけだと動作はしていても見た目が崩れます。
- バージョン差異:slim-select は v1 系と v2 以降で書き方が変わりました。この記事は現行の v4 を前提にしています。古い記事のコードをコピペするとエラーになることがあるので注意しましょう。
エラーの原因が分からないときの調べ方は、エンジニアの仕事は「知っていること」より「調べられること」も参考にしてみてください。
まとめ
importmap を使うと、npm や node_modules を持ち込まずに JavaScript ライブラリを導入できます。手順は「pin する → Stimulus で import する → view で紐付ける → CSS を読む」の4つ。React や Vue も同じ要領で pin できます。ビルドツールを増やさず、Rails 標準の仕組みだけで完結できるのは、少人数開発では大きなメリットです。
Rails のフロントエンド周りをもう少し整えたい方は、RailsにTailwind CSS v4を導入する方法や、Rails の実装パターンをまとめた rails ブログ機能の実装方法7選もあわせてどうぞ。
スポンサーリンク
