まず、Webpackとは
webpackとは、簡単に言うと、「JavaScript」「CSS」「画像やフォント」といった静的アセット(JavaScriptモジュール)を束ねることができるツール
のことです。
私たち開発者にとって使いやすい方法でフロントエンドのコードを書き、そのコードをブラウザで利用しやすい方法でパッケージ化することが目的です。
Webpackのメリット
- 依存関係のあるJavaScriptモジュールを解決
- ファイル間の依存関係を解析して1つのファイルにまとめてくれるので、ファイルの依存関係を解決できます。
- 読み込み順を気にする必要が無くなり、リクエストが一度で良くなり効率的
- リクエスト回数を減らせる(通信回数が減る)ため、サーバーの負担が少なくなります。
- JavaScriptモジュールを簡単にブラウザで扱える形に変換できる
- WebpackはJavaScriptモジュールを結合する前後にコードの変換処理行う事が可能です。これにより、クライアントサイドの環境に影響されづらく、開発効率も向上します。
- loaderやpluginなどが豊富
- JSファイルでないものをJSファイルに変換できるloaderや、Webpackを拡張できるpluginが豊富です。
- 様々なフレームワークで採用されているのでライブラリからサンプルを見つけやすい
- 有名なWebフレームワークでもWebpackが標準で採用されてきているため、サンプルも見つけやすい。
Webpackerとは
Webpackerは、モダンなフロントエンド開発を強力にサポートするWebpackをRuby on Railsで使うためのgemパッケージのことで、標準的なwebpackの設定と合理的なデフォルト設定を提供します。
WebpackerとSprocketsの異なる理由
RailsにはSprocketsが同梱されています。Sprocketsとは、アセットパッケージングツールのことで、Webpackerと機能が重複している部分もあります。
SprocketsはRailsで使われる前提で設計されており、統合方法はシンプルで、gemを用いてSprocketsにコードを追加できます。
対してWebpackは、モダンなJavaScriptツールやNPMパッケージとの統合に優れており、より多くのものを統合することができます。WebpackではCSSを管理することもできます。
Webpackerを利用する方が良い場合
- 新しいプロジェクトで「NPMパッケージを使いたい場合
- 最新のJavaScript機能やツールにアクセスしたい場合
上記の場合は、Webpackerを選択すべきです。
Sprocketsを利用する方が良い場合
- 移行にコストがかかるレガシーアプリケーション
- gemで統合したい場合
- パッケージ化するコードの量が非常に少ない場合
上記の場合は、Sprocketsを選ぶべきです。
[参考]WebpackerとSprocketsの対比表
タスク | Webpacker | Sprockets |
---|---|---|
JavaScriptをアタッチ | javascript_include_tag | javascript_pack_tag |
CSSをアタッチ | stylesheet_link_tag | stylesheet_pack_tag |
画像にリンク | image_url | image_pack_tag |
アセットにリンク | asset_url | asset_pack_tag |
スクリプトをrequire | //= require | import または require |
Webpackerのインストール方法
※Webpackerを使うには、Yarnパッケージマネージャー(1.x以上)とNode.js(10.13.0以上)のインストールが必要です。
<新規プロジェクト作成時にインストールする>
rails new
コマンド実行時にオプションを付与することで、新規プロジェクト作成と同時にインストールしてくれる。
$ bundle exec rails new sample_app --webpack
<既存のプロジェクトにインストールする>
以下コマンドを実行する。
$ rails webpacker:install
Webpackerで追加されたファイル一覧
場所 | 説明 |
---|---|
app/javascript | フロントエンド向けJavaScriptソースコードの置き場所 |
app/javascript/packs/application.js | デフォルトのエントリーポイント |
bin/webpack | webpackでコンパイルを実行 |
bin/webpack-dev-server | webpack-dev-serverを実行 |
config/webpacker.yml | Webpackerのgemを設定 |
config/webpack/environment.js | ローダーやプラグインの設定 |
babel.config.js | Babel(JavaScriptコンパイラ)の設定 |
postcss.config.js | PostCSS(CSSポストプロセッサ)の設定 |
.browserslistrc | Browserlist(対象ブラウザを管理する)設定 |
node_modules/ | node.jsのモジュール群の保管場所 |
package.json | node.jsの依存関係を解決 |
Webpackerでフレームワークを統合
Webpackerには、有名なJavaScriptフレームワークやツールのサポートも多数含まれています。
これらのフレームワークやツールは、新規プロジェクト作成時にrails new sample_app --webpack=<フレームワーク名>
のような方法で作成するか、rails webpacker:install:<フレームワーク名>
のように個別のコマンドラインタスクで作成することができます。
主なフレームワーク統合コマンド
フレームワーク | コマンド | 説明 |
---|---|---|
Angular | rails webpacker:install:angular | AngularとTypescriptのセットアップ |
ERB | rails webpacker:install:erb | JavaScriptファイル内でのERBサポートのセットアップ |
React | rails webpacker:install:react | ReactJSのセットアップ |
TypeScript | rails webpacker:install:typesctipt | プロジェクトで用いるTypescriptのセットアップ |
Vue | rails webpacker:install:vue | VueJSのセットアップ |
使い方
JavaScriptをWebpacker経由で利用する
Webpackerをインストールすると、デフォルトではapp/javascripts/packsディレクトリ配下にのJavaScriptファイルがコンパイルされて独自のpackファイルとしてまとめられます。
たとえば、app/javascript/packs/application.jsというファイルが存在すると、Webpackerはapplicationという名前のpackを作成
します。
このpackは、<%= javascript_pack_tag "application" %>
というERBコードが使われているRailsアプリケーションで追加されます。これによって、application.jsが変更されるたびに再コンパイルされ、ページを読み込むとコンパイル後のpackが使われます。
import 'javascripts/application.js'; // javascripts/application.js配下のファイルをインポート
import 'stylesheets/application.scss';
require.context('images/', true);
packを多数作成するとコンパイルのオーバーヘッドが大きくので、app/javascript/packsディレクトリにはwebpackのエントリーファイルだけを置き、それ以外のものを置かない
ことが重要です。
以下はソースコード構造の例です。
app/javascript:
├── packs:
│ # ここにはwebpackエントリーファイルだけを置くこと
│ └── application.js
│ └── application.scss
└── javascripts:
│ └── sample.js
└── stylesheets:
│ └── sample.scss
└── images:
└── logo.svg
CSSをWebpacker経由で利用する
Webpackerでは、PostCSSプロセッサを用いてCSSやSCSSのサポートを即座に利用可能です。
CSSコードをpackにインクルードするには、まずCSSファイルをトップレベルのpackファイルにインクルードします。
JavaScriptの時と同様の手順でインポートすることで、webpackがCSSファイルをダウンロードに含められるようになります。
import 'javascripts/application.js';
import 'stylesheets/application.scss'; // stylesheets/application.scsss配下のファイルをインポート
require.context('images/', true);
実際にWebページで読み込むには、ビューのコードに<%= stylesheet_pack_tag "application" %>
を追加します。
静的アセットをWebpacker経由で利用する
Webpackerのデフォルト設定では、画像やフォントなどの静的アセットもすぐに使用可能です。
この設定では、様々なファイルのフォーマットに対応する拡張子が多数含まれており、webpackはそれらの拡張子も生成されたmanifest.jsonファイルに追加します。
webpackのおかげで、以下のコード例のように静的アセットをJavaScriptファイル内で直接インポートできます。インポートされた値は、そのアセットへのURLを表します。
import myImageUrl from '../images/my-image.jpg'
// ...
let myImage = new Image();
myImage.src = myImageUrl;
myImage.alt = "I'm a Webpacker-bundled image";
document.body.appendChild(myImage);
Webpackerの静的アセットをRailsのビューで参照するには、WebpackerにバンドルされるJavaScriptファイルで明示的にrequireする必要があります。
Sprocketsとは異なり、Webpackerはデフォルトでは静的アセットをインポートしない
点にご注意ください。
ディレクトリはapp/javascriptを起点とする相対パスです。テンプレートではimagesというディレクトリ名になっていますが、app/javascriptの中であれば任意のディレクトリ名に変更できます。
import 'javascripts/application.js';
import 'stylesheets/application.scss';
require.context("/images", true) // 静的アセットをインポート
静的アセットは、public/packs/mediaディレクトリ以下に出力
されます。
(例)
app/javascript/images/my-image.jpgにある画像をインポート
↓
public/packs/media/images/my-image-abcd1234.jpg
ActionViewヘルパーとWebpackerヘルパーの対比表
ActionViewヘルパー | Webpackerヘルパー |
---|---|
favicon_link_tag | favicon_pack_tag |
image_tag | image_pack_tag |
環境ごとのWebpacker設定について
Webpackerにはデフォルトで「development」、「test」、「production」の3つの環境があります。webpacker.yml
ファイルに環境設定を追加することで、環境ごとに異なるデフォルトを設定できます。また、Webpackerは環境設定を追加するためにconfig/webpack/.js ファイルを読み込みます。
development環境でWebpackerを実行
Webpackerには、development環境で実行する./bin/webpack
と./bin/webpack-dev-server
という2つのbinstubファイルが同梱されています。
これらのbinstubファイルは、環境に応じて適切な設定ファイルや環境変数が読み込まれる
ようになっています。
development環境のWebpackerは、デフォルトでRailsページが読み込まれると必要に応じて自動的にコンパイル
を行います。つまり別のプロセスの実行は不要であり、コンパイルエラーは標準のRailsログに出力されます。
これを変更するには、config/webpacker.ymlファイル
をcompile: false
に変更します。
bin/webpack
を実行すると、packを強制的にコンパイルします。
webpack-dev-serverのプロセスは、app/javascript/packs/*.jsファイルの変更を監視して変更時に自動的に再コンパイルし、ブラウザを再読み込み
します。
Yarnを使おう
Yarnとは、2016年にFaceBookが公開したJavaScriptのパッケージマネージャです。
今後は、YarnでJSやCSSのパッケージを管理し、モジュールバンドラをWebpackerで利用するのが主流になるようです。
Yarnは、常に最新のJavaScriptライブラリを提供してくれてかつ自動でバージョン管理も行ってくれます。
Yarnのメリット
-
npmより高速でインストール出来る
-
npmより厳密にモジュールのバージョンを固定可能
- yarn.lockファイルで、各パッケージのインストールバージョンを固定できる。
-
npmの同時使用が可能
- npmと同じでpackage.jsonが使えるため、同一プロジェクトでnpm or yarnで固定する必要が無い。
Yarnの使い方
Yarnのインストール
※どちらの方法でも良い。
$ npm install -g yarn
$ brew install yarn
バージョン確認
$ yarn -v
package.jsonの生成
※プロジェクトにまだpackage.jsonがない場合に以下のコマンドで生成可能。
$ yarn init # npm initと同義
yarnでパッケージをインストール
$ yarn # npm installと同義
パッケージの追加
パッケージのインストールとpackage.jsonへの追加が可能。
$ yarn add [パッケージ名] # npm install --saveと同義
パッケージのアンインストール
$ yarn remove # npm uninstallと同義
グローバルインストール
$ yarn global add [パッケージ名]
すでにインストールされたファイルが削除されていないことを確認
$ yarn install --check-files
終わりに
これで少しだけでもWebpackerに近付けたんでは無いでしょうか?
今後は主流となるであろうgem、Webpackerはいずれ学習しなければならない時が来ると思います。
その時に慌てて学習するのでは無く、今から前もって知識として身に付けておきましょう!!
参考
[Webpacker の概要]
(https://railsguides.jp/webpacker.html)
[yarnとは]
(https://qiita.com/akitxxx/items/c97ff951ca31298f3f24)