Rails6.0でWebpackerがデフォルトのJavascriptsのコンパイラーになりました。
Webpackerを使うことでWebpackが用意している様々な機能が使えるようになりますし、SplitChunksで簡単に最適化も行えます。
Webpackerを使うことでWebpackが用意している様々な機能が使えるようになりますし、SplitChunksで簡単に最適化も行えます。
なので以前のRailsのバージョンを使ってアプリを構築している人は、SporocketsからWebpackerへの移行を考えていると思います。
でも肝心の移行方法は、Railsのオフシャルドキュメントでは軽く触れているだけで、十分ではありません。
1.まずはwebpackerGemをGemfileに加えます
ここでsprockets gemは残しておきましょう。cssのコンパイルにまだ使いますし、残しておいてもお互いの干渉はありません。
2.Webpackerのコンフィギュレーションを行います
Webpackerの公式ページに詳しいコンフィギュレーションがありますが、基本以下の4つのファイルの設定です、
- /config/webpack/loader/custom_loader.js
- /config/webpack/loader/erb.js
- /config/webpack/production.js
- /config/webpack/development.js
まずjson-loaderとyaml-loaderの設定をcustom_loader.jsで行います。
次に .js.erbファイルが使えるようにrails-erb-loaderを読み込みます。これはRails自体に必要なのではないかな。。。
つまりproduction.jsとdevelopment.jsの設定です。production.jsもdevelopment.jsもconfig/webpack/environment.jsから引継いでいます。
例ではproduction.jsですが、development.jsは以下の部分が違うだけです。
process.env.NODE_ENV = 'development';
3./app/javascript のフォルダーを作る
ここが新たなjavascriptsのホームフォルダーとなります。
4./app/javascript以下にpacksとvendorsを作る
- Packs - カスタムjavascriptをここに移動する。
- Vendor - サードパーティのjavascriptをここに移動する。
5.application.jsを/app/javascript/packsに作って必要な読み込みを行う
例ではrails-ujsとRails Activestorageを読み込んでいます。
ここで
require("@rails/ujs").start()
のラインはCSRF セキュリティーエラーを起こさないために非常に重要です。
まはRailsはテスト環境ではデフォルトでCSRF tokenを使っていないのでrequire("@rails/ujs").start()の必要性を見過ごしてしまう危険性があるので注意してください。
またjquery-ujsからrails-ujsに全面移行することを勧めます。この移行に関しては改めて記事にしました。
ここで
require("@rails/ujs").start()
のラインはCSRF セキュリティーエラーを起こさないために非常に重要です。
まはRailsはテスト環境ではデフォルトでCSRF tokenを使っていないのでrequire("@rails/ujs").start()の必要性を見過ごしてしまう危険性があるので注意してください。
またjquery-ujsからrails-ujsに全面移行することを勧めます。この移行に関しては改めて記事にしました。
6./app/assets/javascriptsにあったjavascriptsファイルを/app/javascript/packsに移動
ほぼ全てのカスタムjavascriptsを移動します。
ほぼ全てというのは、実際123ishでは、日本語表示に必要な.js.erbファイルは /app/assets/javascripts/i18n/jp.js.erbに残して、sprockets で個別にコンパイルして読み込んでいます。
特別な理由がなければjavascriptsは/app/javascript/packsに入れておきます。
ほぼ全てというのは、実際123ishでは、日本語表示に必要な.js.erbファイルは /app/assets/javascripts/i18n/jp.js.erbに残して、sprockets で個別にコンパイルして読み込んでいます。
特別な理由がなければjavascriptsは/app/javascript/packsに入れておきます。
7.グローバル変数を設定
sprocketsと違ってWebpackerではグローバル変数を使う場合、改めて設定する必要があります。
以下の例はexample1というグローバル変数をexample1.jsで定義して、example2.jsで使う例を示しています。
以下の例はexample1というグローバル変数をexample1.jsで定義して、example2.jsで使う例を示しています。
8.application.jsでカスタムjavascriptsを読み込む
Requireを使って以下のように読み込みます。
9.application.jsをapplication.html.erbで呼び込む
これはRailsのフレームワークです。
10.テスト
必須です。
123ishはビヘイビア駆動開発で一通りのテストを使って動作を確認します。勿論マニュアルによるテストも必要なんですけどね。
最後に
Webpackerへの移行によってより高度なjavascriptsの読み込み最適化を行う事が出来るようになるので是非行いたいところですよね。
オフィシャル移行ガイドを読んだときには、簡単に出来ると思ったのですが、初めてみたら結構大変でした。というかガイドにはGemの読み込みしか書いてないです。
でも実際の移行は全般的に影響が出てくる可能性があるので、様々なシナリオをチェックするインテグレーションテストがあることが大前提です。もし網羅的にチェックできるインテグレーションテストのセットが内容であれば、移行は勧めません。
全てのjavasctipsをWebpackerに移動すればいいかというとそうでもありません。敢えてsprocketsを使ってコンパイルしているjavascriptsもあります。
とはいえ、今後Webpack周りでのコードの読み込み最適化技術がより進むと考えられるので、テスト環境など条件が整っていればWebpackerへの以降は早めに行うことをお勧めします。
オフィシャル移行ガイドを読んだときには、簡単に出来ると思ったのですが、初めてみたら結構大変でした。というかガイドにはGemの読み込みしか書いてないです。
でも実際の移行は全般的に影響が出てくる可能性があるので、様々なシナリオをチェックするインテグレーションテストがあることが大前提です。もし網羅的にチェックできるインテグレーションテストのセットが内容であれば、移行は勧めません。
全てのjavasctipsをWebpackerに移動すればいいかというとそうでもありません。敢えてsprocketsを使ってコンパイルしているjavascriptsもあります。
とはいえ、今後Webpack周りでのコードの読み込み最適化技術がより進むと考えられるので、テスト環境など条件が整っていればWebpackerへの以降は早めに行うことをお勧めします。