jsbundling-rails README(翻訳)
jsbundling-rails gemは、esbuild、rollup.js、webpackのいずれかを用いてJavaScriptコードをバンドルし、Railsのアセットパイプラインで配信します。このgemが提供するのは、新しいRailsアプリケーションで上述の好みのバンドラーを利用できるインストーラと、バンドルした出力ファイルをGitなどのソースコード管理に登録されない形でapp/assets/buildsディレクトリに保持する規約です(インストーラはこのディレクトリをデフォルトで.gitignoreに追加します)。
この方法で開発を行うには、ターミナルでyarn build --watch
を実行してバンドラーをwatchモードで起動しておきます(puma-devなどを使っていない場合は、Railsサーバーを別のターミナルで実行してください)。また、./bin/dev
を実行すればRailsサーバーとJavaScriptビルドウォッチャーをまとめて起動できます(cssbundling-railsを使っている場合はCSSビルドウォッチャーも起動します)。
このバンドラーがプロジェクトディレクトリ内のJavaScriptファイルの変更を検出するたびに、以下の1を2にバンドルします(設定済みの他のエントリポイントもすべて同様にバンドルされます)。
app/javascript/application.js
app/assets/builds/application.js
<%= javascript_include_tag "application", defer: true %>
と記述する標準的なアセットパイプラインの手法を用いて、ビルド出力をレイアウト内で参照できるようになります。
アプリケーションをproduction環境にデプロイすると、assets:precompile
タスクにjavascript:build
タスクがアタッチされ(package.json
にあるすべてのパッケージ依存関係がyarnでインストールされるようにするため)、続いてyarn build
を実行してすべてのエントリポイントをdevelopment環境のときと同様に処理します。アセットパイプラインは後者のファイルを拾い上げてダイジェスト化し、他のアセットパイプラインファイルと同様にpublic/assetsディレクトリにコピーします。
これと同じことが、テストでバンドラーがtest:prepare
にアタッチするときにも行われ、テスト開始前にJavaScriptコードが確実にバンドルされるようになります。ただし、現時点ではRailsのtest:*
タスク(test:all
や test:controllers
など)のみが対象である点にご注意ください(rails test
はtest:prepare
を読み込まないので対象に含まれません)。
利用するテストライブラリでtest:prepare
rakeタスクが定義されていない場合は、テストを開始する前にテストスイートでjavascript:build
を実行してJavaScriptコードがバンドルされるようにしておいてください。
概要は以上です。
バンドラーのオプションは、package.json
ファイル内のbuild
スクリプトで設定することも、インストーラが生成するファイルで設定することもできます(rollup.jsの場合はrollup.config.js
、webpackの場合はwebpack.config.json
: なおesbuildにはデフォルトの設定ファイルフォーマットがありませんが、esbuildをAPIとして使うハックを用いるつもりはありません)。
既にWebpackerを使っていて、jsbundling-railsに移行すべきかどうかを検討中の方は、Webpacker(Shakapacker)とjsbundling-railsの比較を参照してください。Webpackerからの移行方法についてはWebpacker→jsbundling-rails+webpackアップグレード手順を参照してください。
Webpackのcode splittingやhot module reloadingなどの機能を使いたい方は、Webpackerの公式forkであるShakapackerの利用をご検討ください。
インストール
システムにnodeとyarnをインストールしておく必要があります。また、npx 7.1.0以降も必要です。
以下を実行します。
./bin/bundle add jsbundling-rails
を実行./bin/rails javascript:install:[esbuild|rollup|webpack]
を実行
Rails 7以降は、新規アプリケーション作成時に利用するバンドラーをrails new myapp -j [esbuild|rollup|webpack]
のように事前に指定できます。
FAQ
Q1: Windowsで*.*
のようなglob構文が使えない場合の回避策はありますか?
esbuildのデフォルトのビルドスクリプトは、複数のエントリポイントを自動コンパイルするためにapp/javascript/*.*
というglob構文に依存しています。Windowsではこのglob構文はデフォルトで利用できないので、package.json
ファイル内のビルドスクリプトを変更して、コンパイルしたいエントリポイントのリストを手動で追加する必要があります。
Q2: esbuildがapplication.cssを上書きしてしまいます
esbuildを利用している場合は、application.js内でCSSをインポートすると、ビルド時にapp/assets/builds/application.js
ファイルと app/assets/builds/application.css
ファイルが両方作成されます。後者のファイルはcssbundling-railsで生成される app/assets/builds/application.css
ファイルと競合します。
解決方法は、esbuildまたはcssbuindlingのいずれかの出力ファイル名(およびその参照)を変更することです。どちらの名前もpackage.json
ファイルで指定されます。
Q3: JavaScriptコードで静的アセットを参照する方法は?
仮にapp/javascript/images/example.png
という画像があり、esbuildでビルドしたフロントエンドコード内でこの画像を参照する必要があるとします。
app/javascript/images/example.png
に画像を作成する。package.json
ファイル内の"scripts"
エントリと"build"
エントリの下で、 esbuildスクリプトに--loader:.png=file
オプションを追加することで、pngファイルをbuildディレクトリにコピーするようesbuildに指示する。- esbuildを実行すると、pngファイルが
app/assets/builds/example-5SRKKTLZ.png
のような形でコピーされる。 - フロントエンドコードでは、
import Example from "../images/example.png"
のように画像を元のファイル名で参照できる。 - これで、画像ファイル自身をインポートファイル名で参照できるようになる(例: Reactの場合は
<img src={Example} />
)。 - 画像へのパスは
/assets/example-5SRKKTLZ.png
に解決される(この画像はアセットパイプラインによって配信される)。
ライセンス
JavaScript Bundling for Rails is released under the MIT License.
関連記事
The post jsbundling-rails README(翻訳) first appeared on TechRacho.
概要
MITライセンスに基づいて翻訳・公開いたします。