基本

Ruby on RailsのビューでJavaScriptファイルを読み込む

Ruby on Railsでは、JavaScriptファイルをビューから読み込む方法がいくつかあります。Railsのバージョンやアセットパイプラインの種類(Sprockets、Webpacker、importmap等)によって方法が異なります。この記事では、JavaScriptファイルの配置場所と読み込み方法、モジュールのインポートについて解説します。

基本的な使い方

Railsではjavascript_include_tagヘルパーを使ってJavaScriptファイルを読み込みます。レイアウトファイルで読み込むのが一般的です。

app/views/layouts/application.html.erb
<head>
  <%= javascript_include_tag "application" %>
</head>

この1行でapp/assets/javascripts/application.js(Sprockets使用時)が読み込まれます。Webpackerを使用している場合はjavascript_pack_tagを使います。

app/views/layouts/application.html.erb
<head>
  <%= javascript_pack_tag "application" %>
</head>

JavaScriptファイルの配置場所

Railsのバージョンやアセット管理方法によって、JavaScriptファイルの配置場所が異なります。

方式 配置場所 読み込みタグ
Sprockets app/assets/javascripts/ javascript_include_tag
Webpacker app/javascript/packs/ javascript_pack_tag
importmap(Rails 7+) app/javascript/ javascript_importmap_tags

ESモジュールのインポート

Webpackerやimportmapを使っている場合は、ES6のモジュールシステムでファイル間のインポート/エクスポートができます。

app/javascript/utils/helper.js
// エクスポート
export function formatDate(date) {
  return date.toLocaleDateString("ja-JP");
}

export function truncateText(text, length) {
  if (text.length <= length) return text;
  return text.substring(0, length) + "...";
}
app/javascript/controllers/main.js
// インポート
import { formatDate, truncateText } from "../utils/helper";

document.addEventListener("DOMContentLoaded", () => {
  const today = formatDate(new Date());
  console.log(today);
});

exportで関数やクラスを公開し、importで必要なものだけを読み込みます。これにより、コードをモジュールごとに分割して管理できます。

ページ固有のJavaScript

特定のページでのみJavaScriptを読み込みたい場合は、content_forを使います。

app/views/layouts/application.html.erb
<head>
  <%= javascript_pack_tag "application" %>
  <%= yield :head_scripts %>
</head>
<body>
  <%= yield %>
  <%= yield :page_scripts %>
</body>
app/views/posts/show.html.erb
<% content_for :page_scripts do %>
  <script>
    document.addEventListener("DOMContentLoaded", () => {
      // この記事ページでのみ動くJavaScript
      const likeBtn = document.getElementById("like-btn");
      likeBtn.addEventListener("click", () => {
        // いいね処理
      });
    });
  </script>
<% end %>

<h1><%= @post.title %></h1>
<p><%= @post.content %></p>
<button id="like-btn">いいね</button>

Stimulus(Rails 7標準)

Rails 7以降では、Stimulusというフレームワークが標準で採用されています。HTMLのdata属性でJavaScriptの振る舞いを宣言的に定義できます。

app/javascript/controllers/hello_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["name", "output"]

  greet() {
    this.outputTarget.textContent =
      "こんにちは、" + this.nameTarget.value + "さん!"
  }
}
app/views/posts/index.html.erb
<div data-controller="hello">
  <input data-hello-target="name" type="text" placeholder="名前を入力">
  <button data-action="click->hello#greet">挨拶する</button>
  <span data-hello-target="output"></span>
</div>

Stimulusコントローラーはapp/javascript/controllers/に配置すると自動的に読み込まれるため、個別にインポートする必要がありません。

ポイント

Rails 7以降ではimportmapがデフォルトのJavaScript管理方式です。npm/Yarnを使わずにJavaScriptの依存関係を管理でき、ビルドステップが不要になります。

注意

Turbolinks(またはTurbo)が有効な場合、従来のDOMContentLoadedイベントはページ遷移時に発火しません。代わりにturbo:loadイベントを使うか、Stimulusコントローラーを使用してください。

まとめ

  • JavaScriptの読み込みはアセット管理方式(Sprockets/Webpacker/importmap)で異なる
  • javascript_include_tagjavascript_pack_tagで読み込む
  • ES6モジュール(import/export)でファイルを分割管理できる
  • content_forでページ固有のJavaScriptを読み込む
  • Rails 7以降はStimulusでJavaScriptの振る舞いを宣言的に定義する
  • Turbo使用時はDOMContentLoadedの代わりにturbo:loadを使う