SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Railsによるクライアントサイド開発入門

Rails 7におけるクライアントサイド開発の全体像とアセット管理の新たな選択肢

Railsによるクライアントサイド開発入門 第1回

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

Rails 7で増えるアセット管理の選択肢

 Rails 7では、Webpackerが標準でなくなりましたが、これに替わるアセット管理方式の選択肢が増えます。このために、4つの新しいGemライブラリが追加されました。これらが、propshaft、importmap-rails、jsbundling-rails、cssbundling-railsです。PropshaftまたはSprocketsに、他のライブラリをアセット管理方式に合わせて組み合わせていく形になります。図3に、ライブラリの組み合わせとアセット管理方式の違いをまとめておきます。詳細は次回以降で取り上げていきますので、ここでは概略だけを示します。

図3 ライブラリとアセット管理

図3 ライブラリとアセット管理

Webpackerが非標準になったわけ

 Rails 7において、Webpackerの使用を前提としなくなったのは、以下の技術的な背景があるとRailsの開発者であるDHH氏のブログ記事では述べています。

(1)ES6が主要Webブラウザでサポートされるようになった

 スマートフォン用を含めた主要なWebブラウザがES6をサポートし、ES6で書かれたJavaScriptコードをトランスパイルなしに実行できるようになりました。ES6は、クラス、モジュール、アロー関数などモダンなJavaScriptプログラムに必須とされる構文をサポートしている初めてのバージョンであり、これをトランスパイルなしに実行できることは、BabelないしWebpackの必要性を大きく下げるものになるわけです。

(2)HTTP/2が普及した

 HTTP(HyperText Transfer Protocol)の新しいバージョンであるHTTP/2がWebサーバ、Webブラウザともに普及が進んだことで、必ずしもHTTP/1.1にこだわる必要がなくなりました。長らく使われてきたHTTP/1.1には、リソースの要求の都度にコネクションの確立が必要という大きな問題がありました。比較的軽量で、その替わり数が多くなりがちなJavaScriptファイルやCSSファイルといったリソースをWebクライアントが都度要求すればその頻度は膨大となります。これは、負荷の大きなコネクションの確立も相まって、パフォーマンス悪化の原因となってきました。HTTP/2では、単一のコネクションでリソースの要求を続けて行うことができ、この問題を解決したことでモジュールバンドラーの必要性を大きく下げています。また、テキストベースであったHTTP/1.1に対してHTTP/2ではバイナリベースの通信を行うので、リクエストヘッダのエンコードが不要になることなどもパフォーマンス的に有利に働きます。

(3)Import Mapsが一部のWebブラウザだが利用可能になった

 さらに、後述するImport Mapsにより、インポートするJavaScriptモジュールをモジュール名だけで記述できるようになったことで、コード上での管理が容易になりました。ES6では、JavaScriptファイルに含まれる変数や関数をエクスポートし、それを別のJavaScriptファイルでインポートして利用するモジュールの仕組みが導入されましたが、この際インポートするモジュールはモジュールの場所を絶対/相対パスで指定する必要があり、それを記述する場所が多くなれば管理が煩雑になるという問題がありました。そこで、Node.jsのようにモジュールを名前だけで参照できれば便利ということで、Import Mapsの仕組みが考えられました。Import Mapsを使うと、モジュールの名称と場所を一元管理でき、モジュールを利用する側はその名前だけを記述すればよくなっています。

新しいアセットパイプラインPropshaft

 Propshaftは、Sprocketsに替わるアセットパイプラインのためのライブラリです。Railsアプリケーション作成時に-aオプションを指定することで、デフォルトになっているSprocketsに替わりPropshaftを使用することを指示できます。

 PropshaftがSprocketsと大きく異なるのは、トランスパイル、圧縮・連結などの処理を行わないことです。単にダイジェストをアセットのファイル名に付加して公開フォルダにコピーするだけなので、高速に動作します。トランスパイル、圧縮・連結が不要なら、Sprocketsに替わりPropshaftを使用すればよいわけです。

図4 Propshaftによるアセットパイプライン

図4 Propshaftによるアセットパイプライン

 また、asset-path("ファイル名")というCSS関数が用意されており、アセットのプリコンパイル時にurl("/assets/image-….svg")のようなダイジェストを用いたファイル名に変換してくれますので、CSSにおけるアセットの参照も容易となっています。

Import Mapsを自動化するimportmaps-rails

 importmaps-railsは、Import Mapsの機能をRails上でサポートするGemライブラリです。Railsアプリケーション作成時にはデフォルトでこのimportmaps-railsがインストールされますので、Sprockets+Import MapsがRails 7のアセット管理におけるデフォルト構成と言えます。

 Import Mapsでは、バージョン管理されたファイル名やダイジェストに対応したファイル名を使わずに、それらとは切り離された論理名でWebブラウザから直接JavaScriptモジュールをインポートすることができます。これにより、モジュールをバンドリングしたりする必要性がなくなりました。

 Import Mapsを使うHTMLには、実際のファイル名と論理名のマッピングをJSON形式で指定しておきます。JavaScriptのコード中では、この論理名を指定してimport文を記述するだけです。これで、Webブラウザが論理名を実際のファイル名に変換して、モジュールのインポートを行ってくれます。

 Railsでは、config/importmap.rbファイルにDSL構文を使ってマッピングの設定を記載しておきます。以下は、importmap-railsによって作成されるconfig/importmap.rbファイルの内容です。

config/importmap.rb
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は主に、論理名と実際のファイル名の対応をマッピングに追加します。pin_all_fromは、指定したディレクトリ以下のファイルをマッピングに追加します。ビュー側では、javascript_importmap_tagsヘルパーを使い、必要なタグを生成します。以下は、/app/views/layouts/application.html.erbに記述されているヘルパーの呼び出しです。

/app/views/layouts/application.html.erb
<%= javascript_importmap_tags %>

 この呼び出しで、必要な<script>タグが自動的に生成されます。なおImport Mapsは、執筆時点でGoogle ChromeやMicrosoft Edgeなどの一部のWebブラウザでしかサポートされていませんが、shim(既存コード修正のためのコード)を使用することで利用可能になります。importmaps-railsでは、自動的にES Module Shimsというモジュールが読み込まれて、Import MapsをサポートしないWebブラウザでもImport Mapsが利用できるようになっています。

バンドラーを使用するjsbundling-railsとcssbundling-rails

 jsbundling-railsは、Webpackやesbuild、rollup.jsといったモジュールバンドラーの使用をサポートするGemライブラリです。Railsアプリケーション作成時に-jオプションを指定してバンドラーを選択できます。Webpackerの新規開発が中止されたことで、WebpackをRails 7においても引き続き使いたいといった場合には、このjsbundling-railsを使ったアセットパイプラインの構築がひとつの選択肢となります。

 また、jsbundling-railsとは直接の関係はないですが、開発中止となったWebpackerの代替とされているShakapackerをインストールして使うのも、もうひとつの選択肢です。この場合には、Gemfileを編集するなどしてShakapackerのGemライブラリをインストールします。

 cssbundling-railsは、BootstrapやDart Sass、PostCSSなどをアプリケーションに組み込む際に必要に応じて使用します。

Railsの環境構築

 次回以降、Railsによるクライアントサイド開発について見ていきますが、必要に応じてアプリケーションを作成し、その構成を見ていきます。そのために、読者の手元にもRailsの開発環境を作っておくことをお勧めします。ここでは、macOSを例に開発環境の構築について概要のみ紹介します。

 環境構築は、以下の手順で行います。

  1. Homebrew(macOS用のパッケージマネージャー)がなければインストール
  2. rbenv(Rubyのインストーラ)をHomebrewでインストール
  3. Rubyをrbenvでインストール
  4. Railsをインストール

 Homebrewがインストールされていない場合には、まずはこれをインストールしておきます。macOS(またはLinux)用パッケージマネージャーのページにアクセスして表示されるシェルスクリプトを実行すると、それだけでHomebrewがインストールされます。 

 次に、rbenvをHomebrewでインストールします。rbenvがインストールできたら、rbenvでインストール可能なバージョンを確認し、バージョン3.1.0がリストにあることを確認してインストールを行います。インストールできたら、使用するバージョンを3.1.0に設定します。

% brew install rbenv
…略…
% rbenv install -l	インストールできるバージョンの確認
…略…
3.1.0
…略…
% rbenv install 3.1.0	バージョン3.1.0をインストール
…略…
% rbenv global 3.1.0	バージョン3.1.0をアクティブにする

 ログイン時の設定を~/.zshrcファイルに下記の内容で追加します。ファイルがなければ新規に作成して下さい。

/~.zshrc
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init - zsh)"

 ここで、sourceコマンドで~/.zshrcファイルを読み込むか、あるいはターミナルを開き直して、PATHの設定などを反映させます。最後にRailsをインストールします。

% gem install rails
…略…
35 gems installed

 ここで、ターミナルを開き直すと、インストールしたRailsのコマンドが有効になります。これで、Railsを使う準備は整いました。

まとめ

 今回は、Ruby on Rails 7について、そのアセット管理を中心に取り上げました。Railsにおけるクライアントサイド開発サポートの変化を振り返りながら、概略をお伝えできたのではないかと思います。次回は、Rails 7で大きく刷新されたアセット管理について掘り下げて紹介したいと思います。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Railsによるクライアントサイド開発入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook <個人紹介> WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/15673 2022/04/04 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング