Dcoker上に構築したRailsで、Webpackerを使ってvueファイルなどをコンパイルすると、デフォルトの状態ではコンパイルにとても時間がかかります(数十秒ほど、、)
あまりにも遅すぎて、「遅い!」と叫びたくなるほどです。コーヒーを飲んだりトイレに行く機会が生まれますが全く実用的ではありません。
ここでは、コンパイル速度を劇的に改善するとても簡単な方法を2つ紹介ています。
webpack-dev-serverを使う
Railsコンテナ起動中に、コンテナの中に入りbin/webpack-dev-server
を実行します。これだけで劇的に速度が改善します。
bin/webpack-dev-server
webpack-dev-serverとは?
webpack-dev-serverはwebpackの開発サーバーを起動するコマンドです。webpackerにデフォルトで入っています。
通常のコンパイルはコンパイル結果をファイルとして出力しますが、webpack-dev-serverを使うとメモリにファイルを出力します。このため、高速化することができます。
更に、ファイルの変更を自動監視するため、変更後に保存をすると、そのタイミングでコンパイルが走ります。
とても便利な機能ですが、コンパイルのたびにメモリをどんどんと消費していくので、ファイルの変更を頻繁にすることがない本番環境では使いません。開発環境のみで使用します。
手前についている bin/ はbinディレクトリの中にある、webpack-dev-severを実行するという意味です。./bin/webpack-dev-server
もやっていることは同じです。
(参考)Github webpack/webpack-dev-server
webpack-dev-serverの使用実例
既にコンテナが起動している場合や、コンテナ起動時に合わせて実行する場合などで、手順が変わるので、パターン別にまとめておきます。
Railsコンテナが既に起動している場合
Railsコンテナが既に起動している場合は、起動しているコンテナの中に入ってから、bin/webpack-dev-serverを実行します。
$ docker exec -it <Railsコンテナ名> bash
# bin/webpack-dev-server
実例
$ docker exec -it rails-vue-web bash
root@59229383d91c:/rails-vue# ./bin/webpack-dev-server
ℹ 「wds」: Project is running at http://localhost:3035/
ℹ 「wds」: webpack output is served from /packs/
ℹ 「wds」: Content not from webpack is served from /rails-vue/public/packs
ℹ 「wds」: 404s will fallback to /index.html
ℹ 「wdm」: wait until bundle finished: /packs/js/main-4c47d2a1061da7d4bba9.js
ℹ 「wdm」: Hash: 654c7ccc69cf925d0c08
Version: webpack 4.46.0
Time: 21160ms
Built at: 07/14/2021 11:10:17 AM
Asset Size Chunks Chunk Names
js/application-c4a75b572e9b964789b4.js 515 KiB application [emitted] [immutable] application
js/application-c4a75b572e9b964789b4.js.map 579 KiB application [emitted] [dev] application
js/main-11b245485189537982a4.js 3.75 MiB main [emitted] [immutable] main
js/main-11b245485189537982a4.js.map 4.17 MiB main [emitted] [dev] main
manifest.json 730 bytes [emitted]
media/images/mountain-83434a53.jpg 210 KiB [emitted]
ℹ 「wdm」: Compiled successfully.
Railsコンテナ起動時に実行する場合
Railsコンテナ起動時に、bin/webpack-dev-serverを合わせて実行することもできます。
docker-compose.ymlがあるディレクトリで次のコマンドを実行します。
$ docker-compose up -d && docker-compose exec <Railsのサービス名> bin/webpack-dev-server
dオプション(detached)を使ってRailsコンテナをバックグラウンドで起動した後に、webpack-dev-serverを実行しています。
実例
$ docker-compose up -d && docker-compose exec web bin/webpack-dev-server
Starting rails-vue-db ... done
Starting rails-vue-web ... done
ℹ 「wds」: Project is running at http://localhost:3035/
ℹ 「wds」: webpack output is served from /packs/
ℹ 「wds」: Content not from webpack is served from /rails-vue/public/packs
ℹ 「wds」: 404s will fallback to /index.html
ℹ 「wdm」: wait until bundle finished: /packs/js/main-190ff4ffb5da3c8f9c01.js
ℹ 「wdm」: Hash: 654c7ccc69cf925d0c08
Version: webpack 4.46.0
Time: 12627ms
Built at: 07/15/2021 3:07:35 AM
Asset Size Chunks Chunk Names
js/application-c4a75b572e9b964789b4.js 515 KiB application [emitted] [immutable] application
js/application-c4a75b572e9b964789b4.js.map 579 KiB application [emitted] [dev] application
js/main-11b245485189537982a4.js 3.75 MiB main [emitted] [immutable] main
js/main-11b245485189537982a4.js.map 4.17 MiB main [emitted] [dev] main
manifest.json 730 bytes [emitted]
media/images/mountain-83434a53.jpg 210 KiB [emitted]
ℹ 「wdm」: Compiled successfully.
更に効率化する(SplitChunksPluginの利用)
コンパイルを更に効率化するために、Webpacker 4では、SplitChunks(スプリットチャンクス)プラグインを使うことができます。
SplitChunksとは?メリット
SplitChunksとはWebpacker 4で使える追加機能です。
通常のコンパイルは、各ファイルに書かれている内容をそのまま出力していきます。
SplitChunksを使うと、それぞれのファイルで共通するモジュールがある場合に、各ファイルの相違点だけと、そのモジュール単体をコンパイルすることで、重複する内容のコンパイルを省くことができます。
無駄なコンパイルが発生しないので、高速化につながります。
(参考)Webpack SplitChunks Plugin
SplitChunksの導入
導入はとても簡単です。2ステップで終わります。
environment.jsの編集
config/webpack/environment.jsに次の1行を追記します。
environment.splitChunks()
これで、WebpackerにSplitChunksを使うことを宣言できます。
実例
const { environment } = require('@rails/webpacker')
const { VueLoaderPlugin } = require('vue-loader')
const vue = require('./loaders/vue')
environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin())
environment.loaders.prepend('vue', vue)
environment.splitChunks() //追記
module.exports = environment
タグの変更
SplitChunksでコンパイルしたファイルを呼び出すために、呼び出し用のタグを変更する必要があります。
javascript_pack_tag
を javascript_packs_with_chunks_tag
に変更します。
実例
<%= javascript_pack_tag 'main' %>
<%= stylesheet_pack_tag 'main' %>
↓
<%= javascript_packs_with_chunks_tag 'main' %>
<%= stylesheet_packs_with_chunks_tag 'main' %>
以上でSplitChunksの設定は完了です。後はコンパイルすれば、SplitChunksで生成したファイルを使ってブラウザを描画します。
(参考)SplitChunksの確認
SplitChunksが正しく機能しているか確認します。Chromeの開発ツールのSourceタブで読み込んでいるファイルを見ると分かりやすいです。
デフォルトの状態
デフォルトの状態では、.jsというファイルを読み込んでいます。
SplitChunks利用時
SplitChunks利用時は、chunk.jsというファイルも読み込んでいます。
SplitChunksが正しく機能している状態です。