30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

Steb by Step で剥がす Webpacker

この記事では、Webpackerを使っている Rails アプリからWebpackerを剥がし、webpackを使うようにするための手順を書いていく。

Webpackerを止めたい理由は様々だが、主な理由は以下のような感じだろうか。

  • 現時点ではWebpackerが使用しているwebpackのバージョンは3.xで、最新バージョンに追従できていない
  • webpackの設定の他に、「Webpackerの設定」について学ばなければならず、無駄が多い
  • webpackを直接触れば済む話を、常にWebpackerという仲介者を通して作業しなければならない

手軽にフロントエンド開発環境を導入できる、というのがWebpackerの利点であり、カスタマイズやらアップデートやらが必要になってしまうのならあまりメリットはない、と個人的には感じている。

前回の記事で、Webpackerと Vue を使ったサンプルアプリを作成した。

numb86-tech.hatenablog.com

このアプリからWebpackerを削除し、webpackで Vue コンポーネントなどをビルドできるようにしていく。

この記事のゴールは「ちゃんと動くようにするための仕組みを作る」ことであって、Webpackerが行っていたことを忠実に再現することはしない。
Webpackerを剥がすために必要な作業の全体像を掴み、それを記録しておくことがこの記事の意図であり、細部には踏み込まない。
ただ、スタイルシートを別ファイルとして抽出するなどの基本的な動作は踏襲する。

Webpackerが果たしている主な仕事は以下。

  1. app/javascript/packsに入っているファイルをエントリファイルとして、public/packsにダイジェスト付きでビルドする
  2. マニフェストファイルとしてpubplic/packs/manifest.jsonを生成する
  3. webpack-dev-serverを使うことで、差分を検知し、自動的にビルドやブラウザのリロードを行う
  4. javascript_pack_tagstylesheet_pack_tagで、ビルドされたファイルを読み込める

これをwebpackで実現する。

以下のバージョンで作業している。

Step1 Webpacker の削除

まずは、Webpackerを削除していく。

Gemfileからgem 'webpacker'を削除して、$ bundleを実行。
$ yarn remove @rails/webpackerを実行。
これでライブラリを削除できるが、関連ファイルはまだまだ残っているのでこれらを削除していく。

  • bin/webpack
  • bin/webpack-dev-server
  • config/webpack/development.js
  • config/webpack/environment.js
  • config/webpack/loaders/vue.js
  • config/webpack/production.js
  • config/webpack/test.js
  • config/webpacker.yml

最後に、設定ファイルからWebpackerに関する記述を削除する。

diff --git a/config/environments/development.rb b/config/environments/development.rb
index 4b8cc17..1311e3e 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -1,6 +1,4 @@
 Rails.application.configure do
-  # Verifies that versions and hashed value of the package contents in the project's package.json
-  config.webpacker.check_yarn_integrity = true
   # Settings specified here will take precedence over those in config/application.rb.
 
   # In the development environment your application's code is reloaded on
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 457946a..b4dbe4a 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -1,6 +1,4 @@
 Rails.application.configure do
-  # Verifies that versions and hashed value of the package contents in the project's package.json
-  config.webpacker.check_yarn_integrity = false
   # Settings specified here will take precedence over those in config/application.rb.
 
   # Code is not reloaded between requests.

また、Turbolinksが有効になっている場合は忘れずに無効化しておく。
これが有効になっていると、ページ遷移時に上手く動かなくなる。
Turbolinksと共存させる方法もあると思うが、ここでは扱わない。

Step2 webpack でビルドできるようにする

この時点では Rails との連携は考えず、まずはapp/javascript/packsに入っているファイルをビルドできるようにする。

必要なライブラリをインストールする。

$ yarn add -D webpack webpack-cli
$ yarn add -D css-loader file-loader sass-loader node-sass mini-css-extract-plugin vue-loader@latest
$ yarn add -D webpack-manifest-plugin

webpack@4からは、CSSの抽出にはextract-text-webpack-pluginではなくmini-css-extract-pluginを使うことが推奨されている。
しかし、Webpacker経由で Vue の開発環境を整えた場合はvue-loaderv14が入っており、これがmini-css-extract-pluginに対応していない。そのため、最新バージョンのvue-loaderを入れる必要がある。

次に、プロジェクトのルートディレクトリ直下にwebpack.config.jsを用意する。
もっとよい書き方があるとは思うし、プロジェクトによってはこれではダメかもしれないが、今回扱っているサンプルアプリの場合はこれで問題なく動く。
Babel の対応は次の Step で行う。

const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');


module.exports = (env, argv) => {
  const isProduction = argv.mode === 'production';
  return {
    context: path.resolve(__dirname, 'app/javascript/packs'),
    entry: {
      application: './application.js',
      'application-stylesheet': './application.sass',
      hello_vue: './hello_vue.js',
    },
    output: {
      path: path.resolve(__dirname, 'public/packs'),
      filename: isProduction ? '[name]-[contentHash].js' : '[name]-[hash].js',
    },
    module: {
      rules: [
        {test: /\.(css|sass)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']},
        {
          test: /\.(png|jpg|gif)$/,
          use: [
            {
              loader: 'file-loader',
              options: {
                outputPath: 'images/',
                name: '[name]-[hash].[ext]',
              },
            },
          ],
        },
        {
          test: /\.vue$/,
          exclude: /node_modules/,
          loader: 'vue-loader',
          options: {
            extractCSS: true,
          },
        },
      ],
    },
    plugins: [
      new VueLoaderPlugin(),
      new ManifestPlugin(),
      new MiniCssExtractPlugin({filename: '[name]-[contentHash].css'}),
    ],
  };
}

あとは、npm スクリプトとして"build": "yarn && webpack --mode=production"を登録し、$ yarn buildを実行すれば、public/packsにビルドされる。

Step3 Babel の対応と v7 へのマイグレーション

Rails5.2Webpacker環境で使われる Babel はv6なので、この機会にv7に上げておく。

必要なライブラリをインストール。

$ yarn add -D babel-loader @babel/core @babel/preset-env @babel/plugin-syntax-dynamic-import @babel/plugin-proposal-class-properties

次に、マイグレーションを行うが、公式のツールが便利なのでそれを使う。

github.com

このツールを使うことで、必要なライブラリのインストールなどが行われる。

$ npm i -g babel-upgrade
$ babel-upgrade --write --install

.babelrcの更新も自動的に行われる、はずなのだが、環境によっては実行されなかった。
取り敢えず今回のケースでは以下のようにすればよい。

diff --git a/.babelrc b/.babelrc
index 47cfe92..3233cc0 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,24 +1,31 @@
 {
   "presets": [
-    ["env", {
-      "modules": false,
-      "targets": {
-        "browsers": "> 1%",
-        "uglify": true
-      },
-      "useBuiltIns": true
-    }]
+    [
+      "@babel/preset-env",
+      {
+        "modules": false,
+        "targets": {
+          "browsers": "> 1%"
+        }
+      }
+    ]
   ],
-
   "plugins": [
-    "syntax-dynamic-import",
-    "transform-object-rest-spread",
-    ["transform-class-properties", { "spec": true }]
+    "@babel/plugin-syntax-dynamic-import",
+    "@babel/plugin-proposal-object-rest-spread",
+    [
+      "@babel/plugin-proposal-class-properties",
+      {
+        "spec": true
+      }
+    ]
   ],
-
   "env": {
     "test": {
-      "presets": ["env", "power-assert"]
+      "presets": [
+        "@babel/preset-env",
+        "power-assert"
+      ]
     }
   }
 }

あとはwebpackbabel-loaderを使うようにすればよい。

diff --git a/webpack.config.js b/webpack.config.js
index 89d3790..2fcb99d 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -19,6 +19,11 @@ module.exports = (env, argv) => {
     },
     module: {
       rules: [
+        {
+          test: /\.js$/,
+          include: path.resolve(__dirname, 'app'),
+          use: 'babel-loader',
+        },
         {test: /\.(css|sass)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']},
         {
           test: /\.(png|jpg|gif)$/,

これで、ビルドの際に Babel によるトランスパイルが行われるようになる。

Babel のバージョンをv7に上げたことで、babel-preset-power-assertの最新バージョン(v3)を使えるようになったので、対応しておく。

$ yarn add -D babel-preset-power-assert@3.0.0

Step4 webpack-dev-server を導入

ビルドは出来るようになったので、次は、webpack-dev-serverを使えるようにする。これがないと自動ビルドや自動リロードが出来ないので、開発に支障をきたしてしまう。

Webpackerをインストールしたときに導入されたwebpack-dev-serverはバージョンが古いので、更新する。

$ yarn add -D webpack-dev-server@latest

コマンドの追加と設定ファイルへの追記を行う。

diff --git a/package.json b/package.json
index 98cde84..b573325 100644
--- a/package.json
+++ b/package.json
@@ -2,6 +2,7 @@
   "name": "webpacker-example",
   "private": true,
   "scripts": {
+    "start": "yarn && webpack-dev-server --mode=development",
     "build": "yarn && webpack --mode=production",
     "test": "jest"
   },
diff --git a/webpack.config.js b/webpack.config.js
index 2fcb99d..4e94f0b 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -52,5 +52,16 @@ module.exports = (env, argv) => {
       new ManifestPlugin(),
       new MiniCssExtractPlugin({filename: '[name]-[contentHash].css'}),
     ],
+    devServer: {
+      publicPath: '/packs/',
+      historyApiFallback: true,
+      port: 3035,
+    },
   };
 }

$ yarn startを実行し、http://localhost:3035/packs/manifest.jsonにアクセスできれば成功である。

Step5 ヘルパータグの実装

次はいよいよ、Rails とのつなぎ込みを行う。
javascript_pack_tagに代わるヘルパータグを作成する。

app/helpers/webpack_bundle_helper.rbとして、以下のファイルを作成した。

require 'open-uri'
# webpackによるビルドファイル読み込み用ヘルパー
module WebpackBundleHelper
  class BundleNotFound < StandardError; end

  def javascript_bundle_tag(entry, **options)
    path = asset_bundle_path("#{entry}.js")

    options = {
      src: path,
      defer: true
    }.merge(options)

    # async と defer を両方指定した場合、ふつうは async が優先されるが、
    # defer しか対応してない古いブラウザの挙動を考えるのが面倒なので、両方指定は防いでおく
    options.delete(:defer) if options[:async]

    javascript_include_tag '', **options
  end

  def stylesheet_bundle_tag(entry, **options)
    path = asset_bundle_path("#{entry}.css")

    options = {
      href: path
    }.merge(options)

    stylesheet_link_tag '', **options
  end

  private

    # アセットが置かれているサーバーを返す
    def asset_server
      port = Rails.env === 'production' ? '3000' : '3035'
      "http://#{request.host}:#{port}/"
    end

    def pro_manifest
      File.read('public/packs/manifest.json')
    end

    def dev_manifest
      # webpack-dev-serverから直接取得する
      OpenURI.open_uri("#{asset_server}packs/manifest.json").read
    end

    def test_manifest
      File.read('public/packs-test/manifest.json')
    end

    def manifest
      return @manifest ||= JSON.parse(pro_manifest) if Rails.env.production?
      return @manifest ||= JSON.parse(dev_manifest) if Rails.env.development?
      return @manifest ||= JSON.parse(test_manifest)
    end

    def valid_entry?(entry)
      return true if manifest.key?(entry)
      raise BundleNotFound, "Could not find bundle with name #{entry}"
    end

    def asset_bundle_path(entry, **options)
      valid_entry?(entry)
      asset_path("#{asset_server}packs/" + manifest.fetch(entry), **options)
    end
end

そしてこれを、テンプレートファイルのなかで使う。

diff --git a/app/views/posts/index.html.erb b/app/views/posts/index.html.erb
index 3bfde83..a418880 100644
--- a/app/views/posts/index.html.erb
+++ b/app/views/posts/index.html.erb
@@ -26,7 +26,7 @@
 
 <%= link_to 'New Post', new_post_path %>
 
-<%= javascript_pack_tag 'application' %>
-<%= stylesheet_pack_tag 'application' %>
-<%= javascript_pack_tag 'hello_vue' %>
-<%= stylesheet_pack_tag 'hello_vue' %>
+<%= javascript_bundle_tag 'application' %>
+<%= stylesheet_bundle_tag 'application-stylesheet' %>
+<%= javascript_bundle_tag 'hello_vue' %>
+<%= stylesheet_bundle_tag 'hello_vue' %>

$ bin/rails s$ yarn startを同時に使って、http://localhost:3000/にアクセスしてみる。
プロダクション環境を確認したい場合は、$ yarn buildしたうえで$ bin/rails s -e productionを実行する。

概ね動いているが、app/javascript/app.vueのなかで使っている画像が表示されていない。

f:id:numb_86:20190109221045p:plain

最後の仕上げとして、この問題を修正する。

Step6 Vueのコンポーネントで使っている画像を表示できるようにする

表示されていない画像だが、確認してみると、http://localhost:3000/images/usa-xxxxx.pngを参照している。

だがこのパスは誤りであり、以下のパスが正しい。

環境 パス
デベロップメント http://localhost:3035/packs/images/usa-xxxxx.png
プロダクション http://localhost:3000/packs/images/usa-xxxxx.png

この問題はプロキシを作成して対応することにした。

まず、rack-proxyをインストール。
Gemfilegem 'rack-proxy'と追記して、$ bundleを実行すればよい。

次に、lib/tasks/assets_path_proxy.rbという名前でプロキシを作成。

require 'rack/proxy'

# Vue のコンポーネントのなかで利用している画像にアクセスできるようにするためのプロキシ
class AssetsPathProxy < Rack::Proxy

  def perform_request(env)
    if env['PATH_INFO'].include?("/images/")
      if Rails.env != 'production'
        dev_server = env['HTTP_HOST'].gsub(':3000', ':3035')
        env['HTTP_HOST'] = dev_server
        env['HTTP_X_FORWARDED_HOST'] = dev_server
        env['HTTP_X_FORWARDED_SERVER'] = dev_server
      end
      env['PATH_INFO'] = "/packs/images/" + env['PATH_INFO'].split("/").last
      super
    else
      @app.call(env)
    end
  end

end

そして、設定ファイルにプロキシを使う設定を書き込む。

diff --git a/config/environments/development.rb b/config/environments/development.rb
index 1311e3e..f4a4f26 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -1,3 +1,5 @@
+require_relative '../../lib/tasks/assets_path_proxy'
+
 Rails.application.configure do
   # Settings specified here will take precedence over those in config/application.rb.
 
@@ -12,6 +14,8 @@ Rails.application.configure do
   # Show full error reports.
   config.consider_all_requests_local = true
 
+  config.middleware.use AssetsPathProxy, ssl_verify_none: true
+
   # Enable/disable caching. By default caching is disabled.
   # Run rails dev:cache to toggle caching.
   if Rails.root.join('tmp', 'caching-dev.txt').exist?
diff --git a/config/environments/production.rb b/config/environments/production.rb
index b4dbe4a..dc6fac5 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -1,3 +1,5 @@
+require_relative '../../lib/tasks/assets_path_proxy'
+
 Rails.application.configure do
   # Settings specified here will take precedence over those in config/application.rb.
 
@@ -14,6 +16,8 @@ Rails.application.configure do
   config.consider_all_requests_local       = false
   config.action_controller.perform_caching = true
 
+  config.middleware.use AssetsPathProxy, ssl_verify_none: true
+
   # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
   # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
   # config.require_master_key = true

これで、表示されるようになる。

f:id:numb_86:20190109105929p:plain

参考資料

Webpacker の基本的な仕組み

webpackではなく、Rails の gem であるWebpackerの話。

Webpackerを止める方法について書く予定だったが、前提であるWebpackerの説明だけで長くなってしまったので別の記事として切り出した。

脱 Webpacker についてはこちら。 numb86-tech.hatenablog.com

rails newから始めて、WebpackerVueを使う方法について説明していく。

以下のバージョンで作業している。

プロジェクトの作成

まず、$ rails new sample_app --webpack --skip-turbolinksでプロジェクトを作成する。

--webpackオプションによって、Webpackerがインストールされた状態でプロジェクトが作成される。

作成されたプロジェクトを見ると、app/javascriptというディレクトリがある。これが、Webpackerに関するディレクトリ。そして、app/javascript/packsに入っているファイルがエントリファイルになる。

以下で、動作確認用の適当なデータを用意する。

$ bin/rails g scaffold post title:string
$ bin/rails db:migrate

$ bin/rails sでサーバーを起動してhttp://localhost:3000/postsにアクセスすれば、ページが表示されるはず。
この画面に、Webpackerでビルドした内容を反映させていく。

javascript_pack_tag

Webpackerでビルドしたスクリプトを読み込むためにはjavascript_pack_tagを使う。

例えば ERB ファイルのなかで<%= javascript_pack_tag 'application' %>とすると、app/javascript/packs/application.jsが読み込まれる。
試しにこれをapp/views/posts/index.html.erbに書いてみる。

app/javascript/packs/application.jsにはconsole.log('Hello World from Webpacker')とあるので、これが実行される。

app/javascript/packs/application.jsを更新してからブラウザをリロードすれば、更新した内容が実行される。
変更を検知して自動的にビルドやブラウザのリロードを行うには、webpack-dev-serverを使う。具体的には、rails sを走らせているときに別プロセスで$ ./bin/webpack-dev-serverを実行すればよい。

ビルドが行われると、public/packs/manifest.jsonが生成・更新される。

{
  "application.js": "/packs/application-xxxxx.js",
  "application.js.map": "/packs/application-xxxxx.js.map"
}

このファイルによって、app/javascript/packsに入っているエントリファイルと、public/packsに生成されたダイジェスト値付きのバンドルファイルを紐づけている。

そして、テンプレートファイル(app/views/posts/index.html.erb)を元に作られたHTMLファイルを見ると、ちゃんとダイジェスト付きのファイルを読み込んでいることが分かる。

<script src="/packs/application-xxxxx.js"></script>

以上のように、ダイジェスト付きのバンドルファイルをビルドし、マニフェストファイルによってバンドルファイルとHTMLを紐付けるのが、Webpackerが果たしている役割である。

なお、$ ./bin/webpack-dev-server実行時に生成されるのはpublic/packs/manifest.jsonのみで、バンドルファイルはメモリ上に存在するだけで実際には生成されない。

プロダクション環境で確認する

先程はデベロップメント環境での確認だったので、プロダクションでも確認してみる。
まずは、ローカルでプロダクション環境を起動するための準備を行う。

  1. config/master.keyが存在するかを確認する。
  2. 環境変数RAILS_SERVE_STATIC_FILESに適当な値を入れる。$ export RAILS_SERVE_STATIC_FILES=1
  3. $ bin/rails db:migrate RAILS_ENV=productionを実行して、プロダクション環境のデータベースにpostsテーブルを作成する。

これでプロダクション環境を利用できるようになる。

まず、分かりやすくするためにpublic/packsを丸ごと削除してみる。
次に、$ bin/rails assets:precompile RAILS_ENV=productionを実行する。デフォルトでは、このコマンドでWebpackerによるビルドも行われる。
public/packsマニフェストファイルとバンドルファイルが生成されているのを確認できる。

$ bin/rails s -e productionでプロダクション環境でサーバーが起動される。
http://localhost:3000/postsを表示すると、正しくバンドルファイルが読み込まれているのを確認できる。

stylesheet_pack_tag

Webpackerでは最初から、.css.sassなどのスタイルシートにも対応している。
stylesheet_pack_tagを使うことで利用できる。

試しにapp/javascript/packs/application.sassを作成し、app/views/posts/index.html.erbで読み込ませてみる。

// app/javascript/packs/application.sass
h1
  border-bottom: 3px solid #000
<%= stylesheet_pack_tag 'application' %>

http://localhost:3000/postsを表示すると、<link rel="stylesheet" media="screen" href="/packs/application-xxxxx.css" />でビルドされたスタイルシートを読み込んでいるのが分かる。

f:id:numb_86:20190109105819p:plain

もちろんpublic/packs/manifest.jsonにも追加されている。

Vue の導入

Webpackerを使えば、React や Vue などのライブラリを簡単に導入できる。 今回は Vue を使ってみる。

$ bin/rails webpacker:install:vueを実行すれば、Vue を使えるようになる。

サンプルファイルとしてapp/javascript/app.vueapp/javascript/packs/hello_vue.jsが自動生成されるので、これを読み込ませてみる。

diff --git a/app/views/posts/index.html.erb b/app/views/posts/index.html.erb
 <%= link_to 'New Post', new_post_path %>
 
 <%= javascript_pack_tag 'application' %>
 <%= stylesheet_pack_tag 'application' %>
+<%= javascript_pack_tag 'hello_vue' %>

ビルドされたpacks/hello_vue-xxxxx.jsが読み込まれ、Hello Vue!と表示されているのが分かる。

f:id:numb_86:20190109105857p:plain

しかし、スタイルが反映されていない。
app/javascript/app.vueには以下の記述があるので、pタグについては中央寄せになっていないとおかしい。

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>

マニフェストファイルを見ると、hello_vue.jsだけでなくhello_vue.cssも出力されているのが分かる。

{
  "application.css": "/packs/application-xxxxx.css",
  "application.css.map": "/packs/application-xxxxx.css.map",
  "application.js": "/packs/application-xxxxx.js",
  "application.js.map": "/packs/application-xxxxx.js.map",
  "hello_vue.css": "/packs/hello_vue-xxxxx.css",
  "hello_vue.css.map": "/packs/hello_vue-xxxxx.css.map",
  "hello_vue.js": "/packs/hello_vue-xxxxx.js",
  "hello_vue.js.map": "/packs/hello_vue-xxxxx.js.map"
}

実はデフォルトでは、Webpackerスタイルシートは別ファイルとして抽出してビルドするようになっている。
そのため、スタイルシートも別途読み込む必要がある。

diff --git a/app/views/posts/index.html.erb b/app/views/posts/index.html.erb
 <%= javascript_pack_tag 'application' %>
 <%= stylesheet_pack_tag 'application' %>
 <%= javascript_pack_tag 'hello_vue' %>
+<%= stylesheet_pack_tag 'hello_vue' %>

これで、スタイルシートも反映される。

f:id:numb_86:20190109105912p:plain

画像の利用

次は画像の扱いを見てみる。

次の2つの画像を用意し、それぞれ、スタイルシートと Vue のコンポーネントで使用する。

diff --git a/app/javascript/app.vue b/app/javascript/app.vue
index e304dc1..cb37cff 100644
--- a/app/javascript/app.vue
+++ b/app/javascript/app.vue
@@ -1,6 +1,7 @@
 <template>
   <div id="app">
     <p>{{ message }}</p>
+    <img src="./images/special/usa.png">
   </div>
 </template>
 
diff --git a/app/javascript/packs/application.sass b/app/javascript/packs/application.sass
index de2c914..c613a49 100644
--- a/app/javascript/packs/application.sass
+++ b/app/javascript/packs/application.sass
@@ -1,2 +1,4 @@
 h1
   border-bottom: 3px solid #000
+p
+  background-image: url('../images/bg.png')

こうすると、次のように表示される。

f:id:numb_86:20190109105929p:plain

マニフェストファイルには、画像について追加されている。

"images/bg.png": "/packs/images/bg-xxxxx.png",
"images/special/usa.png": "/packs/images/special/usa-xxxxx.png"

ユニットテストの導入

Vue コンポーネントユニットテストも導入できる。
詳しくは以下の記事を参照。 numb86-tech.hatenablog.com

Webpacker の設定

Webpackerの設定を確認するには、config/webpack/environment.jsを見ればよい。
このファイルの中に出てくるenvironmentに設定が入っている。

const { environment } = require('@rails/webpacker');

module.exports = environment;

だがこれはWebpacker専用の特殊なオブジェクトなので、environment.toWebpackConfig()webpack本来の設定に置き換える必要がある。

diff --git a/config/webpack/development.js b/config/webpack/development.js
index c5edff9..617a568 100644
--- a/config/webpack/development.js
+++ b/config/webpack/development.js
@@ -2,4 +2,7 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'development'
 
 const environment = require('./environment')
 
+console.log(environment.toWebpackConfig());