Webpacker から Shakapacker へ移行するときの注意点

rails logo

はじめに

こんにちは。システムエンジニアの佐藤です。

WESEEK では Rails を使った Web アプリケーションの開発をするプロジェクトがあります。

この記事では Webpacker から後継である Shakapacker への移行を経験した際に、どのような差があったのか確認した結果を紹介したいと思います。

Webpacker は引退した

Readme.md にもあるように、Webpacker は 5 年間に渡って Rails コミュニティにより提供されてきましたが、Rails 7 からは default の JS ビルドツールとしては import-maps が選択されるようになり引退することになりました。

Rails 7 については、これまでのバンドラも引き続き使うことが可能で、rails new コマンドを実行する際の --javascript オプションには、importmaps (default) に加え、webpack, esbuild, rollup から選択することも可能です。
尚、webpack, esbuild, rollup を選択した場合は jsbundling-rails がインストールされ、この gem が Rails との統合を担うため Webpacker は使われません。

Shakapacker とは

Webpacker の引退は開発の停止ではなく、Rails コミュニティによる開発の停止を意味します。
Shakapacker は Webpacker の公式な後継となる gem であり、引き続き開発が行われています。

先に紹介した jsbundling-rails が Rails の Sprockets と連動して動作するのに対し、Shakapacker (Webpacker) は Sprockets の代替になることが出来る点や、Webpack の code splitting, Hot Module Replacement (HMR) 機能が利用できる点が特筆できる違いだと思います。

その他の比較については https://github.com/rails/jsbundling-rails/blob/main/docs/comparison_with_webpacker.md に詳しく紹介されているのでご覧ください。

Webpacker からの移行先として Shakapacker を選択する理由

Shakapacker vs jsbuilding-rails

Shakapacker は webpack の wrapper なので webpack と切り離すことが出来ません。
一方で、jsbundling-rails は webpack, esbuild, rollup を選択して使うことが出来ます。

Sprockets の代替として Webpacker を使っていて、特にバンドラを変更する予定がない場合は Shakapacker を選ぶことで少ない工数でライブラリをアップデートをすることが出来ます。
(webpack 5 以降へアップデートする場合は Webpacker は対応していないため Shakapacker へ移行する必要があります)

その他の選択肢

DHH 氏による blog Rails 7 will have three great answers to JavaScript in 2021+ では、Rails 7 の default である import-maps を使う場合や、Rails を API モードで利用してフロントエンドと分離するという手段も紹介されています。
API モードは継続して提供され続けるとのことですので、プロジェクトの状況を鑑みて検討をするとよいでしょう。

Webpacker と Shakapacker の違い

Webpacker と Shakapacker は名前も違いますが、Webpacker v5 から fork され Shakapacker として v6 がリリースされているので v5 以前を Webpacker、v6 以後を Shakapacker と呼んで差し支えないでしょう。
bin/webpackerbin/shakapacker などへリネームされています)

Webpacker から Shakapacker へのマイグレーションガイドにあるように、Shakapacker は、よりスリムな Webpack のラッパーになりました。
webpacker.yml を介して webpack を設定する機会は極力減り、config/webpack/environment.js で webpack の設定をする機会が増えることになりました。
そのため、Webpacker に比べて Shakapacker では webpack の config をそのまま記述する機会が増えています。

Webpacker から Shakapacker へ移行するときの注意点

細かく挙げると多くの違いがありピックアップ出来ていない点もあります。
また、アプリケーションの設定によっては注意すべき点となる・または注意すべき観点が変わる可能性があるので Shakapacker の CHANGELOG.md は目をとおしてください。

あくまで筆者が変更点として認識した・注意した点が以下です。

  • node_modules 配下は babel トランスパイル対象にならなくなった
  • Webpacker でおなじみの設定ファイルの構造が変わった
    • ex. config/webpack/environment.js がなくなった
  • NODE_ENVRAILS_ENV を元に設定されるようになった
    • これまで RAILS_ENV=staging などの production 相当の環境があった場合、NODE_ENV=production に fallback せずに development が設定されるようになった
  • Webpacker では dependencies であった依存ライブラリが peerDependencies に変わった
  • Webpacker の Rails view helper が色々変わった
    • asset_pack_path の出力先が media から static に変わった
    • javascript_pack_tag は 1 回だけしか使用できなくなった
    • javascript_pack_tag が render する javascript タグに defer オプションがデフォルトで付くようになった
    • image_pack_tag が追加された
  • assets ファイルの読み込み先として node_modules を自動で追加する処理がなくなった
  • デフォルトでは app/javascript/packs ディレクトリ配下は直下のファイルのみが bundle される対象となった
  • webpacker.yml の設定が変わった
    • webpacker_precompile 設定が追加された
  • assets:precompile 時に yarn install されなくなった

最後に

Webpacker から Shakapacker へ移行する機会がある方の一助になれば幸いです。