Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Ruby on RailsアプリケーションでWebpackerを使用する—詳細解説

インターネット黎明期には、Webサイトはずっとシンプルで、インタラクティブ性も高くありませんでした。テクノロジー、デバイス、プログラミング言語の進化に伴い、Webサイトはより複雑になり、画像やCSSスタイルシートといったアセットを含む複数のファイルで構成されるようになりました。

Webサイトのインタラクティブ性が高まるほど、より多くのJavaScriptコードが必要になります。こうしたコードを使用するには、すべてのHTMLコードファイルをscriptタグで読み込む必要があります。しかしこのアプローチはエラーを招きやすく、すべてのファイルを正しい順序で読み込むことを覚えておかなければならず、順序を間違えるとコードが動作しません。Webpackツールを使えば、これらの問題が解決します。Webpackerは、WebpackとRailsアプリケーションをつなぐブリッジの役割を果たします。

この記事ではWebpackerを深く掘り下げ、その内部動作を詳細に解説します。内容を最大限に価値あるものにするため、以下のセクションに分けて説明します:

  • ハイレベル概要 — 深掘りの前に、WebpackとWebpackerの全体像を説明します。より高度なトピックへの準備としてお読みください。
  • 構造の説明 — 複数のファイルを扱うため、なぜその構造が採用されているのか、一般的な目的とどう関わっているのかを理解しておくと良いでしょう。
  • 構成要素の解説 — Webpackセットアップで最も重要なファイルを調査します。それらの動作を知ることは、効率的でトラブルのない開発プロセスに不可欠です。
  • 環境別のセットアップ — 最後のパートでは、Webpackerが開発環境と本番環境でどう動作するかを説明します。

この記事を読めば、WebpackとWebpackerが何であるか、なぜRailsアプリケーションで必要なのかがわかります。Webpackerの内部構造を深く理解することで、このツールがWebpackとどう連携し、Railsアプリケーションとどう通信しているかが明確になります。

深掘りの前に

いきなり深いところへ潜る前に、まず準備が必要です。ハイレベル概要は、あらゆるテクノロジーを扱う際の優れた出発点となります。ツールの目的と解決する問題を、内部構造に深入りせずに理解できるからです。

Webpackとは

すでに触れたように、WebpackはJavaScriptファイルのコードを整理し、エラーを防ぎ、Webサイトのパフォーマンスを向上させるのに役立ちます。コードをバンドルという単位にまとめます。

バンドルとは、最初に作成される依存関係グラフを尊重しつつ、複数のモジュールがインテリジェントに配置されたファイルのことです。このプロセスのおかげで、コードが期待通りに動作し、特定のライブラリのコードを呼び出す前に、それが確実に読み込まれていることが保証されます。

最新版のRailsでデフォルトで使用されるツールはWebpackだけではありません。プロジェクトを生成すると、BabelとPostCSSの設定ファイルも一緒に作成されます。PostCSSはJavaScriptでCSSを変換するツール、BabelはモダンなJavaScriptをブラウザ対応を気にせず書けるようにするJavaScriptコンパイラです。

Webpackerとは

Webpackerは、WebpackをRailsアプリケーションと統合するツールです。JavaScriptライクなアプリケーションの設定と開発を容易にし、本番環境向けに最適化します。

ソースコードはgemとして提供され、開発サーバーが付属しています。このサーバーのおかげで、JavaScriptファイルに変更を加えるたびにサーバーを停止・再起動する必要がなく、アプリケーション開発が非常に高速になります。

本格的な深掘り

Webpackがなぜ作られ、WebpackerがRailsアプリケーションでどんな役割を果たすかがわかったところで、Webpackerの内部構造に焦点を当て、ファイルの整理方法、開発プロセスの高速化、本番環境向けのファイル最適化の仕組みを見ていきましょう。

Webpackerは、最新版のRailsでは標準で利用できます。新しいプロジェクトを作成する前に、Nodeのバージョンが10.17.0以上であることを確認してください。rails newコマンド実行時にwebpacker:installコマンドが自動的に呼び出されます。

Webpackerのファイル構造

インストールコマンドを実行すると、以下のファイルが作成されます:

  • config/webpacker.yml — デフォルト設定と環境別設定を含むメインの設定ファイル
  • config/webpacker/ — 環境ごとのJavaScript設定ファイルが作成されるディレクトリ
  • bin/webpack — webpackを呼び出してバンドルを作成する実行ファイル
  • bin/webpack-dev-server — 開発サーバーを起動する実行ファイル。JavaScriptファイルに変更があるたびにwebpackをリロードします

設定ファイルの構造

Webpackerのメイン設定ファイルはconfigディレクトリ配下のwebpacker.ymlです。一方、Webpackの設定は環境ごとに別々のファイルとしてconfig/webpackディレクトリ配下に保存されます。

Webpackerの設定

デフォルトでは、設定ファイルには多くのエントリ(デフォルト設定と、特定の設定を上書きするための環境別セクション)が含まれます。最も重要な設定を見てみましょう:

  • source_path — アプリケーション内のJavaScriptファイルの主要なソース。デフォルトはapp/javascriptで、通常この値を変更する必要はありません。
  • source_entry_pathsource_path配下で、パックファイル(エントリーポイント)を置くディレクトリ名。デフォルトはpacksディレクトリです。
  • public_root_path — ブラウザからアクセス可能なアプリケーション内のディレクトリパス。一般的なRailsアプリケーションではpublicディレクトリです。
  • public_output_path — Webpackerがファイルをコンパイルした際、public_root_path配下に作られる出力ディレクトリ。デフォルトはpacksですが、任意の名前に変更可能です。
  • webpack_compile_output — trueに設定すると、ファイルコンパイル時に出力メッセージが表示されます。コンパイル失敗時に気づけるため便利です。

開発環境用セクションには、開発サーバーの設定も含まれています。これにより、開発環境ではサーバーを再起動せずにファイルをコンパイルできます。

Railsコンソールやコードレベルから設定にアクセスしたい場合は、Webpacker.manifest.configを呼び出せば、設定クラスのインスタンスが返されます。

Webpackの設定

各環境ごとに設定ファイルがありますが、すべてのファイルでメインの環境設定ファイルconfig/webpack/environment.jsがインポートされます。この環境設定ファイルには、Webpackのデフォルト動作を変更するカスタムプラグインの読み込みや、ファイルコンパイル用のカスタムルールの追加を行う場所があります。

パックファイルの構造

パックファイルはapp/javascript/packsディレクトリ配下に置かれます。各パックファイルは、コンパイルプロセス開始時にWebpackerからエントリーポイントとして扱われます。

デフォルトのパックファイル

新しいRailsプロジェクトを生成すると、application.jsというデフォルトのパックファイルが以下の内容で作成されます:

import Rails from "@rails/ujs";
import Turbolinks from "turbolinks";
import * as ActiveStorage from "@rails/activestorage";
import "channels";

Rails.start();
Turbolinks.start();
ActiveStorage.start();

ご覧のように、最初にライブラリをインポートし、必要に応じて初期化メソッドを呼び出しています。importを呼ぶと、システムは指定されたNodeモジュールやローカルライブラリを探します。従来のアプローチでは、scriptタグでページソースに含めると自動的に初期化されていたため、明示的な初期化は不要でした。

パックファイルのベストプラクティス

パックファイルに通常のJavaScriptコードを書いて実行することは可能ですが、推奨しません。ベストプラクティスは、パックファイルをクリーンに保ち、ライブラリのインポートと初期化のみを行い、その他のロジックはpacksディレクトリの外に置くことです。

パックファイルをアプリケーションに読み込む

パックファイルは自動的にWebサイトのソースに読み込まれません。アセットパイプラインと同様に、ビュー内で特別なタグを使う必要があります:

<%= javascript_packs_with_chunks_tag 'application' %>

このメソッドは内部でどう動作するのでしょうか?裏側では、config/webpacker.ymlに記述したデータを保持するWebpacker設定を呼び出します。エントリーポイントディレクトリ(この場合はapp/javascript/packs)内でapplication.jsファイルを探します。以下のコードで確認できます:

Webpacker.manifest.config.source_entry_path

エントリーが見つかると、WebpackerはRailsにデフォルトで搭載されているActionViewライブラリのヘルパーであるjavascript_include_tagメソッドを呼び出します。このメソッドは1つ以上のソースを受け取り、ビューに直接適用できるscriptタグを返します。

開発サーバー

Webpacker開発サーバーのエントリーポイントは、binフォルダ内にあるwebpack-dev-serverという実行ファイルです。サーバー起動のプロセスは5つのステップで構成されます:

  • 環境の設定 — NodeとRailsの環境名を設定します。環境が指定されていない場合、開発環境で実行されるとみなされます。
  • 設定の読み込み — 前のステップで設定された環境に対応する設定でconfig/webpacker.ymlを読み込みます。
  • コマンドオプションの検証 — サーバーコマンドに適切なオプションが渡されたかチェックします。例えば、config/webpacker.ymlで指定していないのに--httpsオプションが与えられた場合、エラーを投げます。
  • ポートの可用性確認 — 指定されたポートが使用可能か確認します。他のプログラムがすでに使用している場合、エラーを投げてconfig/webpacker.yml内のwebpackサーバー設定を更新するよう促します。
  • webpack serveコマンドの実行node_modulesディレクトリが存在すればその中でコマンドを実行し、なければyarn経由で実行します。プログラムはconfig/webpack/ディレクトリ内のいずれかのファイルを指す設定オプションをコマンドに渡します。

これでサーバーが稼働し、コードをその場でコンパイルするため、JavaScriptファイルを修正するたびにサーバーを再起動して、webpackが新しいコードでバンドルを作成できたか確認する必要がなくなります。

開発サーバーのコードは非常にシンプルです。YAML形式の設定ファイルから設定を読み込み、JavaScript形式の適切な設定を直接webpack serveコマンドに渡すだけです。手動で実行することもできますが、組み込みコマンドを使えば適切なコマンド引数を自分で気にする必要がありません。

本番環境向けファイルのコンパイル

Webpackerを使用するアプリケーションをデプロイする場合、単にassets:precompileタスクを呼び出せばOKです。Webpackerがwebpacker:compileタスクを自動的にフックしているからです。

webpacker:compileタスクは内部で何をしているのでしょうか?掘り下げてみましょう。主に以下の2つを行います:

  • メインの呼び出しを2つのブロックでラップし、NODE環境が設定され、Webpackerのログが標準出力に出力されることを保証します。
  • Webpackを呼び出し、そのログを解析してアクションが成功したかどうかを判定します。

これでpublic/packs/jsディレクトリを確認すると、コンパイル済みのファイルが見つかるはずです。これらをサーバーにデプロイします。

まとめ

Webpackerが内部でどう動作しているかを学んできました。Webpackerは、WebpackライブラリとRailsアプリケーションをつなぐブリッジとして、RubyでWebpackを設定し、JavaScriptコードをアプリケーション内で簡単に扱えるようにします。

記事全体を振り返り、Webpackerの主要要素を再確認しましょう:

  • 設定config/webpacker.ymlにあり、JavaScriptファイルとパックを置くディレクトリをWebpackerに指示します
  • パック — Webpackerがコンパイルを開始する単一のエントリーポイント。ここでインポート・初期化されたライブラリは自動的にコンパイルされます
  • 開発サーバー — ファイルをその場でコンパイルするシンプルなスクリプト。JavaScriptファイルを修正するたびにサーバーを再起動する必要がありません
  • コンパイルタスク — Webpackを呼び出し、publicディレクトリ配下にファイルをコンパイルするシンプルなRakeタスク。本番サーバーにデプロイしてエンドユーザーに提供できます
  • ビューヘルパー — コンパイル済みファイルをビュー内で読み込むためのヘルパー

経験の浅い開発者にとってWebpackerは少し「魔法」のように見えるかもしれませんが、実際はWebpackをRubyらしく扱えるようにするシンプルなライブラリに過ぎません。

P.S. Ruby Magicの記事をいち早く読みたい方は、Ruby Magicニュースレターを購読して、記事を1つも見逃さないようにしましょう!

  1. RailsでTailwind CSSを使う方法|導入から実践的なスタイリングまで徹底解説

    CSSは魔法のような存在ですが、同時に時間のかかる作業でもあります。美しく、機能的で、アクセシブルなサイトは使っていて心地よいものですが、自分でCSSを一から書くのは骨の折れる仕事です。近年はBootstrapをはじめとする多くのCSSフレームワークが登場し、その中でもTailwind CSSは特に注目を集めています。 RailsにはTailwindが標準搭載されていませんが、この記事では新しいRuby on RailsプロジェクトにTailwind CSSを追加する方法を解説します。これにより、デザイン実装にかかる時間を大幅に節約できるでしょう。さらに、Tailwindのユーティリティクラス

  2. Rails5でのAngularの使用

    あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた