こんにちは、かつコーチです。
CSSやJavaScriptを編集したのに画面に反映されない。
昔のRails記事を参考にしたら Sprockets や Webpacker という単語が出てきて、今の構成と違う気がする。
Rails 8を使い始めた人がよくぶつかる悩みです。
この記事では、Rails 8のデフォルトになったPropshaft(CSS・画像などの静的ファイルを配信する仕組みです)とImportmap(JavaScriptのライブラリをビルドツールなしで読み込む仕組みです)の役割を整理し、CSS/JSを正しく読み込む方法を解説します。
読み終えるころには、アセット周りのエラーで迷わなくなっているはずです。
アセットパイプラインとは?
そもそもアセットパイプラインとは何をするものか
アセットパイプラインとは、CSSやJavaScript、画像などの静的ファイル(アセットと呼びます)を、ブラウザに配信できる形に処理してから届ける仕組み全体を指します。
具体的には、以下のような役割を持ちます。
- ファイルをまとめる、または個別に配信する
- ファイル名にハッシュ値をつけて、ブラウザのキャッシュを適切に更新する
- 本番環境用に圧縮する
Rails 8ではこの役割を、CSS・画像についてはPropshaft、JavaScriptについてはImportmapが担っています。
以前のSprockets/Webpackerとの違い
以前のRailsでは Sprockets がCSS/JSをまとめてコンパイルし、Webpacker がNode.jsのビルドツールと連携してJavaScriptを処理していました。
これらは高機能な反面、Node.js環境の構築やビルド設定が複雑で、初心者がつまずきやすいポイントでした。
Rails 8では、この複雑さを解消するために以下の構成がデフォルトになっています。
| 項目 | 役割 | 特徴 |
|---|---|---|
| Propshaft | CSS・画像・フォントの配信 | シンプルな配信のみ。バンドル処理はしない |
| Importmap | JavaScriptの読み込み | npmやビルド不要。ブラウザのESモジュールをそのまま使う |
CSS/JSの読み込み方
Propshaftによるスタイルシートの読み込み
CSSファイルは app/assets/stylesheets/ 配下に置きます。
/* app/assets/stylesheets/application.css */
body {
font-family: sans-serif;
background-color: #fafafa;
}
.post-card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 16px;
}
レイアウトファイルでは、stylesheet_link_tag を使って読み込みます。
<%# app/views/layouts/application.html.erb %>
<head>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
</head>
Propshaftはこのファイルをそのまま配信します。
Sprockets時代のように //= require や *= require_tree . のような特殊な記法(ディレクティブと呼ばれます)を書く必要はありません。
複数のCSSファイルを使いたい場合は、通常のCSSの @import を使うか、それぞれを個別に stylesheet_link_tag で読み込みます。
Importmapによるライブラリの読み込み
JavaScriptライブラリを追加したいときは、bin/importmap コマンドを使います。
例えば Chart.js を追加する場合は次のようにします。
$ bin/importmap pin chart.js
実行すると config/importmap.rb に1行追加されます。
# config/importmap.rb
pin "application"
pin "chart.js", to: "https://ga.jspm.io/npm:chart.js@4.4.1/dist/chart.umd.js"
これで app/javascript/application.js の中で import できるようになります。
// app/javascript/application.js
import "chart.js"
console.log("application.js loaded")
Importmapは、ブラウザが標準で対応しているESモジュールの import 文をそのまま活用しています。
そのため npm install やバンドラー(webpack、esbuildなど)を用意しなくても、外部ライブラリを使えるのが最大の特徴です。
Stimulusコントローラを追加する
Rails 8では、JavaScriptの管理にStimulus(HTMLの data-controller 属性と連携する軽量なJSフレームワークです)を使うのが標準です。
// app/javascript/controllers/hello_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["output"]
greet() {
this.outputTarget.textContent = "こんにちは、かつコーチです!"
}
}
<%# app/views/posts/index.html.erb %>
<div data-controller="hello">
<button data-action="click->hello#greet">挨拶する</button>
<span data-hello-target="output"></span>
</div>
よくあるつまずきポイント・エラー対処
CSSを編集したのに反映されない
私が実際に経験したトラブルです。
application.css を編集してブラウザをリロードしても、見た目が変わりませんでした。
原因は、別のCSSファイルを新規作成しただけで stylesheet_link_tag に指定を追加していなかったことでした。
❌ Before:新しいCSSファイルを作っただけで読み込み設定をしていない
app/assets/stylesheets/
application.css
posts.css # 新しく作成したが読み込まれていない
<head>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
</head>
✅ After:application.cssから@importするか、明示的に読み込む
/* app/assets/stylesheets/application.css */
@import "posts.css";
もしくはレイアウト側で個別に指定する方法もあります。
<head>
<%= stylesheet_link_tag "application", "posts", "data-turbo-track": "reload" %>
</head>
Propshaftはファイルを自動でまとめてはくれないので、「新しいファイルを作ったら、読み込み設定も追加する」ことを忘れないようにしましょう。
Uncaught TypeError: Failed to resolve module specifier エラー
JavaScriptライブラリをインストールせずに import してしまうと、ブラウザのコンソールに以下のようなエラーが出ます。
Uncaught TypeError: Failed to resolve module specifier "chart.js"
これは、config/importmap.rb にライブラリの登録がないまま import している状態です。
❌ Before:pinせずにimportしている
// app/javascript/application.js
import "chart.js"
# config/importmap.rb
pin "application"
# chart.jsのpinがない
✅ After:bin/importmap pinでライブラリを登録してからimportする
$ bin/importmap pin chart.js
# config/importmap.rb
pin "application"
pin "chart.js", to: "https://ga.jspm.io/npm:chart.js@4.4.1/dist/chart.umd.js"
import する前に、必ず bin/importmap pin でライブラリを登録するのが基本の流れです。
まとめ
この記事のポイント
- Rails 8のデフォルトは、CSS・画像がPropshaft、JavaScriptがImportmap
- Propshaftはファイルをそのまま配信するだけで、まとめる処理はしない
- 新しいCSSファイルは、読み込み設定を自分で追加する必要がある
- Importmapは
bin/importmap pinでライブラリを登録してからimportする - Node.jsのビルドツールなしで、シンプルにJS/CSSを扱えるのがRails 8の設計思想
次に読むべき記事
- ビュー(ERB)の基本とレイアウト
- RESTfulなルーティング設計(resources)の考え方
タグ: Ruby on Rails, 中級者向け, フレームワーク基礎