webpacker

webpack

  • CSSJavaScript、画像などWebコンテンツを構成するあらゆるファイル(アセット)を「モジュール」という単位で取り扱い、依存関係を解析して「バンドル」という1つのファイルに最適な形で変換するためのツール。
  • Webpackコマンドを使ってビルドすることで、ビルドされた「バンドル」の中にさまざまなファイルが「コード」として埋め込まれる。これによりファイルのリクエスト数が減少し、ページ読み込み速度が改善する。
loaderとplugin

loader: バンドルする前にtypescriptやsassをjavascriptcssコンパイルすることができる。
plugin: バンドル後にファイルをminifyするなどの処理ができる。

yarn add などでプロジェクトに追加してから、webpack.config.jsで使用方法を設定する。

// webpack.config.js

use: [
  { loader: 'style-loader' },   // (4番目)
  { loader: 'css-loader' },     // (3番目)
  { loader: 'postcss-loader' }, // (2番目)
  { loader: 'sass-loader' }     // (1番目)
]

webpack.configのloaderの配列は、後ろのloaderから先に処理されるので、先に処理したいloaderは配列の末尾に入れる。

babel

新しいJavaScript(ES6+)のコードを古いJavaScript(EC5)のエンジンで実行できるようにコンパイルする。

webpacker

webpackのgemパッケージ。webpackを自前でRailsに導入せずとも簡単にwebpackをRailsに取り込める。

<!-- webpackerのヘルパーメソッド -->

<%= javascript_pack_tag 'application' %>
app/javascript/packs/application.jsを読み込み

<%= stylesheet_pack_tag 'application' %>
app/javascript/stylesheets/application.jsを読み込み

webpackerでできること

webpack.config.jsを作らずともloaderやpluginが使える。config/webpacker.ymlをもとにファイルを書き出す。

自動ビルド
  • (webpack環境で書いたJSは編集ごとにビルドが必要)
  • webpackerではjavascript_pack_tagメソッド実行時に対象となるファイルの更新有無をチェック
  • 更新されていればbin/webpackコマンドを通じてビルドを実行する
webpack-dev-serverを利用したビルド
  • webpack-dev-serverを起動しておくと、webpack管理下のファイルの更新を検知し、すぐにビルドを実行する
  • ビルドした結果はwebpack-dev-serverのメモリ上に展開され、リクエストに応じてビルド後のファイルを返す
  • Railsのサーバではなくwebpack-dev-serverに対しJSファイルのリクエストを送信する必要があるが、webpackerはwebpack-dev-serverの使用・未使用にかからわず同じ設定で利用できるように作られているため、特別な対応を行う必要がない
CSSの抽出

extract: trueである場合(デフォルト)、CSSをJSとは別のファイルとして書き出すことができる。

# config/webpacker.yml

production:
  <<: *default
  extract_css: true
// webpackerの内部のコード
const styleLoader = {
  loader: 'style-loader'
}

  if (config.extract_css) {
    use.unshift(MiniCssExtractPlugin.loader)
  } else {
    use.unshift(styleLoader)  
  }

mini-css-extract-pluginがloaderの配列の先頭に追加される=CSS in JSなCSSを、CSS単品のファイルとして書き出す処理が最後に行われる。 一方style-loaderはCSS in JSを実際にDOMに描画するパッケージ。

webpacker関連の不具合

アプリケーション内でwebpackがどう挙動しているかが把握しにくいというデメリットがある。

ActionView::Template::Error: Webpacker can't find application.css

css_extract:trueとした場合、stylesheet_pack_tag 'application'でapplication.cssを呼び出せないとこのエラーが出る。

パッケージアップデートでの支障

いろいろな関連パッケージがwebpackerに依存しているので、それらの使いたいバージョンがあってもwebpackerが対応するのを待ったりwebpackerのバージョンを上げないとパッケージを更新できない。

webpackerにまつわる設定ファイル一覧

  • app/javascript/packs エントリーファイルを置く場所
  • app/javascript エントリーファイルから読み込まれるファイルを置く場所
  • config/webpacker.yml webpackerの設定ファイル
  • config/webpack/*.js 最終的なwebpackの設定を出力するファイル
  • babel.config.js babel用の設定ファイル
  • .browselistrc コンパイル対象となるブラウザ環境を記述するファイル