Tech Racho エンジニアの「?」を「!」に。
  • 開発

Rails 5: Webpacker公式README -- Webpack v4対応版(翻訳)

本READMEの他に、以下のWebpacker公式ドキュメントの歩き方記事もどうぞ。これら2本で、Webpackerの公式ドキュメントは概観できるかと思います。次は公式のユースケースが欲しいです🍰🍵。

【保存版】Rails 5 Webpacker公式ドキュメントの歩き方+追加情報

概要

MITライセンスに基いて翻訳・公開いたします。

更新や誤りにお気づきの方は@hachi8833までお知らせください。

Rails 5: Webpacker公式README -- Webpack v4対応版(翻訳)

Webpackerを用いることで、JavaScriptのプリプロセッサ兼バンドラーであるwebpack 4.x.x+を簡単に使えるようになり、アプリ的なJavaScriptをRailsで管理できます。Webpackerはアセットパイプラインと共存します。その理由は、Webpackがアプリ的なJavaScriptを主要な対象としているためです。app/assetsの下に居座り続ける画像やCSS、ましてやJavaScript Sprinklesは、Webpackの主要な対象ではありません。

しかし(訳注: Webpackと異なり)WebpackerはCSS/画像/フォントアセットも同様に扱うことが可能なので、アセットパイプラインすら不要になるかもしれません。Webpackerは、コンポーネントベースのJavaScriptフレームワークを独占的に利用する場合に最も適しています。

メモ: masterブランチのコードがついに(訳注: Webpack)v4.x.xになりました。3.x系ドキュメントについては3-x-stableブランチをご覧ください。

必要な環境

  • Ruby: 2.2以降
  • Rails: 4.2以降
  • Node.js: 6.0.0以降
  • Yarn: 0.25.2以降

Webpackerで利用できる機能

  • webpack 4.x.x
  • ES6(ES2015) -- babel経由
  • マルチエントリポイントを用いた自動コード分割
  • スタイルシート: SassとCSS
  • 画像とフォント
  • PostCSS - Auto-Prefixer
  • アセット圧縮、ソースマップ、最小化(minification)
  • CDNサポート
  • React、Angular、Elm、Vueをすぐに利用可能
  • Railsビューヘルパー
  • 拡張および設定可能

インストール方法

Rails 5.1以降のアプリを新規作成するときに--webpackという新オプションでWebpackerを追加できます。

# Rails 5.1以降で利用可能
rails new myapp --webpack

あるいはGemfileに以下のように追加して、

# Gemfile 
gem 'webpacker', '~> 3.5'

# masterを使いたい場合
gem 'webpacker', git: 'https://github.com/rails/webpacker.git'

# 4.x pre-releaseを試してみたい場合
gem 'webpacker', '>= 4.0.x'
yarn add @rails/[email protected]  # 訳注: この行はコマンドで実行

最後に以下を実行してWebpackerをインストールすることもできます。

bundle
bundle exec rails webpacker:install

# Rails 5.0 より前の場合
bundle exec rake webpacker:install

使い方

インストールが終われば、現代的なES6フレーバーJavaScriptアプリをすぐにでも書き始められます。

app/javascript:
  ├── packs:
  │   # ここにはwebpackエントリファイルだけが置かれる
  │   └── application.js
  └── src:
  │   └── application.css
  └── images:
      └── logo.svg

javascript_pack_tagヘルパーを用いて、Railsビュー内でJavaScriptのpackをリンクできます。packファイルでスタイルシートがインポートされる場合は、stylesheet_pack_tagでリンクできます。

<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>

<link rel="prefetch">タグや<img />タグで静的アセットをリンクしたい場合は、asset_pack_pathヘルパーを利用できます。

<link rel="prefetch" href="<%= asset_pack_path 'application.css' %>" />
<img src="<%= asset_pack_path 'images/logo.svg' %>" />

メモ: スタイルシートや静的アセットのファイルをビューから利用するには、それらをパックやエントリファイルにリンクする必要があるでしょう。

開発

Webpackerをインストールすると、./bin/webpack./bin/webpack-dev-serverという2つのbinstubができます。どちらも、それぞれ標準のwebpack.js実行ファイルとwebpack-dev-server.js実行ファイルの薄いラッパーであり、環境に合う設定ファイルや環境変数を正しく読み込むためのものです。

訳注(2018/05/24): 本READMEで言及されているwebpack/webpack-dev-serverは現在メンテナンスモードに移行済みです。現在はdevなしのwebpack-contrib/webpack-serveに移行しましたが、現時点ではRailsのWebpackerリポジトリにまだ導入されていない様子です。新名称の末尾はserverではなくserveなので微妙に紛らわしいです。

追記(2018/10/16) 上記のwebpack-serveは、その後メンテナー不在などの理由によりdeprecatedとなっています。現在は元のwebpack-dev-serverを使うよう指示されています。上の情報は古いのでご注意下さい。

development環境のWebpackerは、デフォルトでは(一括ではなく)必要に応じてコンパイルを実行します。コンパイルは、Webpackerのヘルパーメソッドを用いてpackアセットを参照するときに実行されます。つまり、コンパイルのために別プロセスを走らせる必要がないということです。コンパイルエラーは標準のRailsログに出力されます。

コードのライブリロード機能を使いたい場合や、JavaScriptの量が多すぎてオンデマンドコンパイルが遅い場合は、./bin/webpack-dev-serverまたはruby ./bin/webpack-dev-serverを実行する必要があります。Windowsユーザーは、bundle exec rails sを実行しているターミナルとは別のターミナルでがこれらのコマンドを実行する必要があります。このプロセスはapp/javascript/packs/*.jsファイルの変更を監視して自動的にブラウザ画面を再読み込みして最新表示にします。

# webpack dev server
./bin/webpack-dev-server

# watcher
./bin/webpack --watch --colors --progress

# スタンドアロンでのビルド
./bin/webpack

development用サーバーが起動すると、Webpackerは自動的にすべてのwebpackアセットへのリクエストをこのサーバーにプロキシし始めます。サーバーを停止すると、元のオンデマンドコンパイルに復帰します。

webpack-dev-serverでサポートされている環境変数をWEBPACKER_DEV_SERVER_<オプション名>の形式で利用できます。この環境変数の設定は、設定ファイルよりも常に優先される点と、同じ環境変数をrails serverからも利用できるようにしておかなければならない点にご注意ください。

WEBPACKER_DEV_SERVER_HOST=example.com WEBPACKER_DEV_SERVER_INLINE=true WEBPACKER_DEV_SERVER_HOT=false ./bin/webpack-dev-server

development環境におけるwebpack-dev-serverは、セキュリティ上の理由によりデフォルトでlocalhostをリッスンします。しかし、アプリをローカルLANのIPやVagrantなどのVMインスタンスからアクセス可能にしたい場合は、./bin/webpack-dev-server binstubの実行時に次のようにhostを設定できます。

WEBPACKER_DEV_SERVER_HOST=0.0.0.0 ./bin/webpack-dev-server

メモ: アプリを制限CSP環境(Rails 5.2以降など)で実行する場合は、webpack-dev-serverホストをconnect-srcの「allowed origin」として許可する必要があります。この設定は、Rails 5.2以降のCSPイニシャライザconfig/initializers/content_security_policy.rbに以下のようなスニペットを用いて行えます。

policy.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035' if Rails.env.development?

メモ: Windows環境でこれらのbinstubを実行する場合はrubyをプレフィックスとして追加するのを忘れないように。

Webpackの設定方法

Webpackの設定方法やローダーの変更方法については、docs/webpack.mdをご覧ください。

訳注: 以下記事の「最初に読むもの」もどうぞ。

【保存版】Rails 5 Webpacker公式ドキュメントの歩き方+追加情報

Rails環境のカスタマイズ

Webpackerのconfig/webpacker.ymlは、最初からdevelopment/test/production環境向けに利用できる状態になっています。しかしほとんどのproductionアプリでは開発ワークフローの一端として他の環境も必要になります。Webpacker 3.4.0以降、追加環境についてもすぐ利用できるようになっています。

webpacker.ymlファイルで追加の環境設定を次のように定義できます。

staging:
  <<: *default

  # productionはパフォーマンス向上のためプリコンパイル後の起動に依存
  compile: false

  # パフォーマンス向上のためのmanifest.jsonキャッシュ
  cache_manifest: true

  # stagingのpackを別ディレクトリにコンパイル
  public_output_path: packs-staging

それ以外の場合、Webpackerの設定読み込みはproduction環境にフォールバックします。NODE_ENVに設定できるのはproductionまたはdevelopmentである点にご注意ください。つまり、config/webpacker/*の下に追加の環境ファイルを作成する必要はありません。代わりに、RAILS_ENVを用いて別の設定をwebpacker.ymlで読み込んでください。

たとえば、以下のコマンドを実行するとアセットがproductionモードでコンパイルされますが、config/webpacker.ymlで(staging環境設定が)利用できる場合はそのstaging設定を読み込み、そうでなければproduction環境設定にフォールバックします。

RAILS_ENV=staging bundle exec rails assets:precompile

以下のコマンドを実行すると、developmentモードでコンパイルし、webpacker.ymlにcucumber環境の設定が定義されていればそれを読み込み、なければproduction設定にフォールバックします。

RAILS_ENV=cucumber NODE_ENV=development bundle exec rails assets:precompile

binstubでのコンパイルはdevelopmentモードで行われますが、rakeタスクでのコンパイルはproductionモードで行われる点にご注意ください。

# developmentモードでコンパイル(NODE_ENVが指定されていない場合)
./bin/webpack
./bin/webpack-dev-server

# デフォルトでproductionモードでコンパイル(NODE_ENVが指定されていない場合)
bundle exec rails assets:precompile
bundle exec rails webpacker:compile

アップグレード

Webpackerは、以下のコマンドを実行することで最新の安定版にアップグレードされます。このプロセスには、gemや関連するJavaScriptパッケージのアップグレードも含まれます。

bundle update webpacker
rails webpacker:binstubs
yarn upgrade @rails/webpacker --latest
yarn add webpack-dev-server@^2.11.1

# (プレリリースを含む)最新リリースをインストールする場合
yarn add @rails/[email protected]

Yarn統合

development環境のWebpackerは、デフォルトでyarn統合チェックを実行してローカルのJavaScriptパッケージをすべて最新にします。これはRailsで用いられるbundlerと似ていますが、対象がJavaScriptである点が異なります。システムが古い場合、Railsは初期化を行いません。その場合yarn installを実行してローカルJavaScriptパッケージをアップグレードするよう求められます。

このオプションをオフにするには、Railsのdevelopment環境の設定ファイル(config/environment/development.rb)に新しく設定オプションを追加することでデフォルトの動作をオーバーライドする必要があります。

config.webpacker.check_yarn_integrity = false

Railsのどの環境設定ファイルについても、以下の設定オプションを追加することでこの機能をオンにできます。

config.webpacker.check_yarn_integrity = true

統合

Webpackerは、React、Angular、Vue、Elmとの基本的な統合をすぐに利用できるようになっています。
利用可能なコマンドやタスクの一覧は、bundle exec rails webpackerで表示できます。

Reactを使う場合

WebpackerでReactを使うには、Rails 5.1以降のアプリをrails newするときに--webpack=reactオプションを追加します。

# Rails 5.1以降
rails new myapp --webpack=react

(Webpackerが設定済みの既存Railsアプリの場合はbundle exec rails webpacker:install:reactを実行します)

インストーラはyarmを用いて関連する依存関係を追加し、設定ファイルを変更して、サンプルのReactコンポーネントをapp/javascript/packsに追加します。これを用いてすぐにでもReactを試すことができます。

AngularでTypeScriptを利用する場合

WebpackerでAngularを使うには、Rails 5.1以降のアプリをrails newするときに--webpack=angularを追加します。

# Rails 5.1以降
rails new myapp --webpack=angular

(Webpackerが設定済みの既存Railsアプリの場合はbundle exec rails webpacker:install:angularを実行します)

インストーラはyarnを用いてTypeScriptとAngularのコアライブラリを追加し、それに応じて設定ファイルでいくつかの変更を行います。TypeScriptで記述されたサンプルコンポーネントもapp/javascriptに追加されますので、これを用いてすぐにでもAngularを試すことができます。

development環境でのAngularはデフォルトでJITコンパイラを用います。このコンパイラは、Rails 5.2以降のような制約CSP(Content Security Policy)環境と互換性がありません@ngtools/webpackプラグインを用いて Angular AOTをdevelopment環境で使う手もあります。

または、Rails 5.2以降を利用しているのであればdevelopment環境でunsafe-evalを有効にする方法もあります。有効にするには、config/initializers/content_security_policy.rbに以下のコードを設定します。

  if Rails.env.development?
    policy.script_src :self, :https, :unsafe_eval
  else
    policy.script_src :self, :https
  end

Vueを使う場合

WebpackerでVueを使うには、Rails 5.1以降のアプリをrails newするときに--webpack=vueオプションを追加します。

# Rails 5.1以降
rails new myapp --webpack=vue

(Webpackerが設定済みの既存Railsアプリの場合はbundle exec rails webpacker:install:vueを実行します)

インストーラはyarnを用いてVueや必要なライブラリを追加し、必要に応じて設定ファイルを自動更新します。サンプルコンポーネントもapp/javascriptに追加されますので、これを用いてすぐにでもVueを試すことができます。

Rails 5.2以降を利用している場合は、development環境でunsafe-evalを有効にする必要があります。有効にするには、config/initializers/content_security_policy.rbに以下のコードを設定します。

  if Rails.env.development?
    policy.script_src :self, :https, :unsafe_eval
  else
    policy.script_src :self, :https
  end

詳しくはVueのドキュメントをご覧ください。

Elmを使う場合

WebpackerでElmを使うには、Rails 5.1以降のアプリをrails newするときに--webpack=elmオプションを追加します。

# Rails 5.1以降
rails new myapp --webpack=elm

(Webpackerが設定済みの既存Railsアプリの場合はbundle exec rails webpacker:install:elmを実行します)

Elmライブラリとコアライブラリのパッケージは、yarnとElmを用いて追加されます。
サンプルMain.elmアプリもapp/javascriptに追加されますので、これを用いてすぐにでもElmを試すことができます。

Stimulusを使う場合

WebpackerでStimulusを使うには、Rails 5.1以降のアプリをrails newするときに--webpack=stimulusオプションを追加します。

# Rails 5.1以降
rails new myapp --webpack=stimulus

(Webpackerが設定済みの既存Railsアプリの場合はbundle exec rails webpacker:install:stimulusを実行します)

The Stimulus Handbookを読むか、stimulusjs/stimulusのソースコードで詳しい内容を学べます。

CoffeeScriptを使う場合

WebpackerにCoffeeScriptサポートを追加するには、Webpackerが設定済みの既存Railsアプリでbundle exec rails webpacker:install:coffeeを実行します。

サンプルhello_coffee.coffeeファイルもapp/javascriptに追加されますので、これを用いてすぐにでもCoffeeScriptを試すことができます。

Erbサポートを使う場合

JSテンプレートにErbサポートを追加するには、Webpackerが設定済みの既存Railsアプリでbundle exec rails webpacker:install:erbを実行します。

サンプルhello_erb.js.erbファイルもapp/javascriptに追加されますので、これを用いてすぐにでもErbフレーバーのJavaScriptを試すことができます。

インストールパスについて

デフォルトのWebpackerは、従来のRailsアプリと同様のシンプルな方法でJavaScriptアプリファイルやコンパイル済みwebpackバンドルを配置します。これらのオプションはすべてconfig/webpacker.ymlファイルで設定できます。

デフォルトのwebpackコンパイル設定は、従来のapp/javascript/packs/*(デフォルト)にあるすべてのファイルや、webpacker.ymlsource_entry_pathで設定した任意のパスを対象とし、それぞれ独自の出力ファイル(webpackが呼び出す場合はエントリポイントも)に変換されます。これによって、エントリポイントにしたくないものをpacksディレクトリ以下に配置する必要がなくなります。簡単に言うと、ビューでリンクしたいファイルはすべてpacksディレクトリ内に配置し、それ以外のものはすべてapp/javascriptに配置してください。

たとえばソースディレクトリをapp/javascriptからfrontendに変更し、出力先をassets/packsにしたいのであれば、次のように書けばよいでしょう。

# config/webpacker.yml
source_path: frontend
source_entry_path: packs
public_output_path: assets/packs # 出力先 => public/assets/packs

同様に、webpack-dev-server設定を変更するにはconfig/webpacker.yml`で次のようにできます。

# config/webpacker.yml development:
  dev_server:
    host: localhost
    port: 3035

スタイルシートにJavaScriptコードを含めてホットリロードされるように設定したいのであれば、hmrtrueに変更すればstylesheet_pack_tagからは何も出力されなくなります。production環境やtest環境でのstylesheet_pack_tagは適切なHTMLタグを生成します。

resolved_pathsオプション

Webpackerを追加する既存のアプリでほとんどのアセットがapp/assetsの下やエンジン内に保存されていて、かつそれらをwebpackモジュールで共有したい場合は、config/webpacker.ymlファイルのresolved_pathsを利用できます。これを用いて、webpackがモジュールを解決するときに探索すべきパスを追加できます。

resolved_paths: ['app/assets']

続いて、モジュール内で次のようにインポートします。

// 親ディレクトリ(app/assetsなど)からの相対パスである点に注意
import 'stylesheets/main'
import 'images/rails.png'

注意: パスの追加は慎重に行ってください。さもないとコンパイル速度が低下します。参照の必要なモジュールが1〜2個程度であれば、親ディレクトリ全体ではなく、個別のパスを追加することを検討しましょう。

watched_paths配列

デフォルトでは、遅延コンパイル結果は監視対象パスの下にあるファイルが変更されるまでキャッシュされます。watched_paths配列に新しいパスを追加することで監視対象を設定できます。これはRailsのautoload_pathsとよく似ています。

# config/initializers/webpacker.rb
# またはconfig/application.rb
Webpacker::Compiler.watched_paths << 'bower_components'

デプロイ

Webpackerは新しいwebpacker:compileタスクをassets:precompileにフックします(assets:precompileを実行すると必ず実行される)。Sprocketsを使っていない場合、webpacker:compileは自動的にassets:precompileにエイリアスされます。Sprocketsと同様、rakeタスクもproductionモードでpacksをコンパイルしますが、設定の読み込みにはRAILS_ENVを使います(config/webpacker.ymlがある場合はこれを使う)。

ドキュメント

より詳しいガイドはdocsをご覧ください。

訳注: 以下のWebpacker公式ドキュメントの歩き方記事もどうぞ。

【保存版】Rails 5 Webpacker公式ドキュメントの歩き方+追加情報

ライセンス

WebpackerはMIT Licenseに基いてリリースされています。

関連記事

新しいRailsフロントエンド開発(1)Asset PipelineからWebpackへ(翻訳)

RailsのVue.jsをWebpackerとJestでテストする(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。