WebpackをRailsに導入する方法を比較する: 後編

9a5b0608-318e-5e20-110c-d98fa941d784

こんにちは、エンジニアのケントです。

前編の解説により、webpackerが提供する方法論は

  • js環境構築がとても楽である
  • webpackerが提供する環境に開発がロックインされる

ということがわかりました。

後半ではWebpackとRailsを独立して使う方法を解説し、rubygemのWebpackerを使う方法との比較をしようかと思います。

WebpackとRailsを独立して使う

この方法を実装するにあたってはCookpadさんのブログを参考にさせていただきました。

まず、ルートディレクトリに frontend というディレクトリを作ります。

├── app
│   └── assets
│
├── lib
│   └── tasks
│
└── frontend

そして

├── app
│   └── assets
│
├── lib
│   └── tasks
│
├── frontend
│   ├── src
│   ├── .babelrc
│   ├── .eslintrc
│   ├── package.json
│   ├── webpack.config.js
│   ├── webpack.config.prod.js
│   └── yarn.lock

このように frontend ディレクトリにwebpackの開発に必要なコードを全て詰め込み、frontend/src ディレクトリに主なソースコードを書くスタイルです。

webpackerでは開発環境を定義するファイルが自動生成されましたが、今回の場合は開発環境を定義するファイルを .babelrc .eslintrc webpack.config.js webpack.config.prod.js などといったファイル群によしなに自作していく必要があります。

また、frontend ディレクトリにwebpackによるjsの環境を詰め込んだので、Railsのルートディレクトリからwebpackを起動するコマンドを用意したくなります。なので

├── app
│   └── assets
│
├── lib
│   └── tasks
│       └── webpack.rake
│
├── frontend

といったrakeコマンドを lib/tasks ディレクトリに追加してあげましょう コマンドの中身は

namespace :webpack do
  task build: :environment do
    begin
      result = exec('cd frontend && yarn run build')
    rescue
      print result
    end
  end
end

といった感じです。必要に応じてコマンドはよしなに生やしてください。

そして、最後にwebpackによる成果物の配信先を作る必要があります。

├── app
│   └── assets
│       └── javascripts
│           └── frontends
│
├── lib
│   └── tasks
│       └── webpack.rake
│
├── frontend

配信後は javascript_include_tag で任意のファイルを読み込んでください。

webpackでファイル圧縮をするのでアセットパイプラインは必要ないかもしれませんが、必要が生じた場合はマニフェストファイルも app/assets/javascripts の下に置きましょう。

あとは rails srake webpack:build コマンドをそれぞれ別コンソールから打てば開発をスタートすることができます。

必要に応じて webpack-dev-server をrakeコマンドから叩いてもいいですし、別々のコンソールを開くのが面倒な場合は foreman の導入も検討してください。

デプロイする場合は、capistrano

task :build do
  yarnでnode_modulesを作るコマンド
  webpackのコマンド
end

Rake::Task["assets:precompile"].enhance(%i(build))

と追記しておけば、precompile時にwebpackのコマンドをhookできます。 (この部分はこの方の記事を参考にしました)

環境によってはyarnが環境変数をうまく読んでくれないことがあるので、その場合は上記のコマンドに

'export NODENV_ROOT="nodenvの位置"',
'export NODENV_VERSION="nodeのバージョン"',
'export PATH="$NODENV_ROOT/bin:$PATH"',
'eval "$(nodenv init -)"',
'export PATH="$PATH:$(yarn global bin)"',

と行った環境変数を読むコマンドを泥臭く追記してください。

まとめ

Webpackerを使う方法とWebpackとRails別にする方法の pros & cons をまとめると

  • Webpacker
    • pros
      • 全自動でWebpack環境が作られる。今現在Webpackの知識が少なくても始められる
    • cons
      • Webpackerのレールから外れたくなると相当のWebpackの専門知識と覚悟が必要とされる
  • WebpackとRailsを独立して使う
    • pros
      • 自分のWebpackの知識の範囲内で環境を作れるので、後々のメンテナンスが楽になる
    • cons
      • 最初の段階でWebpackの知識がそれなりに要求される

といった印象でした。

WebpackをRailsのプロダクトに組み込みたい人の判断の助けになれば幸いです。