Rails(8/7)でJSライブラリをimportmapで使う方法【npm不要・slim-select実例】

  • このエントリーをはてなブックマークに追加

スポンサーリンク

「RailsでちょっとしたJavaScriptライブラリを使いたいだけなのに、Webpackやnpmまわりの設定でつまずいた」——そんな経験はありませんか?Rails 7以降は importmap が標準になり、npm・Yarn・node_modules なしで JavaScript ライブラリを導入できるようになりました。この記事では、セレクトボックスを高機能にする slim-select を例に、importmap と Stimulus を組み合わせてライブラリを動かすまでの手順を解説します。Rails 8 でも同じ流れで動きます。

全体の流れ

先に結論から。やることは大きく4ステップです。

  1. ./bin/importmap pin でライブラリを追加する(config/importmap.rb に登録される)
  2. Stimulus コントローラで import して使う
  3. view で data-controller を指定して紐付ける
  4. 必要なら 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選もあわせてどうぞ。

スポンサーリンク

  • このエントリーをはてなブックマークに追加