概要
Rails 5.1 から導入されるというwebpackerを試してみます。
Webpackerとは
Webpacker makes it easy to use the JavaScript preprocessor and bundler Webpack to manage application-like JavaScript in Rails. It coexists with the asset pipeline, as the purpose is only to use Webpack for app-like JavaScript, not images, css, or even JavaScript Sprinkles (that all continues to live in app/assets).
It's designed to work with Rails 5.1+ and makes use of the Yarn dependency management that's been made default from that version forward. It's also currently compatible with Rails 5.0 stable but there's absolutely no warranty it will still be in the future. You can either make use of Webpacker during setup of a new application with --webpack or you can add the gem and run bin/rails webpacker:install in an existing application.
要は従来のasset piplineとwebpackをつかったJSアプリケーションを共存させるための仕組みといったところでしょうか。
環境
macOS Sierra 10.12.2
Ruby 2.3.0
Rails 5.0.1
導入
まずはrails new
$ rails new webpacker-sample
webpackerをインストール
Gemfileに追記してbundle install
1
diff --git a/Gemfile b/Gemfile
index a8f01f7..1e86672 100644
--- a/Gemfile
+++ b/Gemfile
@@ -19,6 +19,8 @@ gem 'jbuilder', '~> 2.5'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
+gem 'webpacker', github: "rails/webpacker"
+
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
$ bundle install
するとRakeタスクにwebpacker用のタスクが追加されます。
$ bin/rake -T | grep webpacker
rake webpacker:compile # compile javascript packs using webpack for production with digests
rake webpacker:install # install webpacker in this application
rake webpacker:install:react # install everything needed for react
webpacker:install
を叩いてみる
$ bin/rake webpacker:install
必要なファイルやコマンド郡が追加されました。
new file: app/javascript/packs/application.js
new file: bin/webpack
new file: bin/webpack-watcher
new file: bin/yarn
new file: config/webpack/development.js
new file: config/webpack/production.js
new file: config/webpack/shared.js
new file: vendor/package.json
new file: vendor/yarn.lock
これでとりあえずwebpackを使う準備が整いました。
package.jsonの中身はこんな感じ。 シンプルにdevDependencies
のみとなっています。
{
"devDependencies": {
"babel-core": "^6.21.0",
"babel-loader": "^6.2.10",
"babel-preset-latest": "^6.16.0",
"coffee-loader": "^0.7.2",
"coffee-script": "^1.12.2",
"path-complete-extname": "^0.1.0",
"rails-erb-loader": "^3.2.0",
"webpack": "beta",
"webpack-merge": "^2.3.1"
}
}
ビルドしてみる
ビルドはbin/
配下に追加されたbin/webpack
,bin/webpack-watcher
,webpack:compile
を使用します。
$ bin/webpack
Hash: 071bb7221801f498ad46
Version: webpack 2.2.0-rc.3
Time: 400ms
Asset Size Chunks Chunk Names
application.js 3.37 kB 0 [emitted] application
application.js.map 3.34 kB 0 [emitted] application
[0] ../app/javascript/packs/application.js 496 bytes {0} [built]
app/javascript/packs/application.js
がビルドされて public/packs/
に application.js
とapplication.js.map
というファイルが生成されました。
ビルド時にはconfig/webpack/*.js
がconfファイルとして使用されます。
また、エントリーポイントはapp/javascript/packs/
配下に配置し、それ以外のファイルはapp/javascript/
に配置する設計となっているそうです。
例えばカレンダーアプリを作成する場合
console.log('Hello, Calendar!')
require('calendar')
のようにファイルを配置してビルドします。
$ bin/webpack
Hash: cafcaf55f1653cfef821
Version: webpack 2.2.0-rc.3
Time: 421ms
Asset Size Chunks Chunk Names
calendar.js 3.22 kB 0 [emitted] calendar
application.js 3.38 kB 1 [emitted] application
calendar.js.map 3 kB 0 [emitted] calendar
application.js.map 3.35 kB 1 [emitted] application
[0] ../app/javascript/calendar/index.js 32 bytes {0} [built]
[1] ../app/javascript/packs/application.js 496 bytes {1} [built]
[2] ../app/javascript/packs/calendar.js 20 bytes {0} [built]
プロダクション用にビルドする場合はrake webpacker:compile
を使用すると、public/packs/digest.json
とハッシュ値つきのjsファイルが生成されます。
また、webpackのウォッチ機能を使いたい場合はbin/webpack-watcher
を使用します。
インクルード
ビルドしたjsをインクルードするには javascript_include_tag
の代わりにjavascript_pack_tag
というヘルパーメソッドを利用します。
<%= javascript_pack_tag 'calendar' %>
このメソッドを使うことでproduction環境ではdigest化されたjsがインクルードされるようになります。
production環境以外でdigest化されたjsをインクルードするにはconfig/environments/*.rb
に下記のように追記します。
config.x.webpacker[:digesting] = true
webpack-dev-server
こちらのPRで追加されました。
bin/webpack-dev-server
で起動します。
以下のように有効化するとjavascript_pack_tag
でlocalhost:8080
(デフォルトポート)でサーブされているjsファイルをインクルードしてくれます。
# Make javascript_pack_tag load assets from webpack-dev-server.
config.x.webpacker[:dev_server_host] = "http://localhost:8080"
その他
Reactを利用する場合はwebpacker:install:react
というrakeタスクでいい感じにファイルを生成してくれます。
ですがこのあたりはまだまだ変わっていきそう?ですね。
react導入サンプル
所感
まだまだwebpacker自体は開発が始まったばかりですが、すでにこれだけでもフロント開発していけそうな気がします。
ServerSideRenderingする場合はreact_on_rails等と組み合わせて使ってもよさそうです。
参考
-
Rail 5.1では
rails new --webpack
とすると自動で追加されるようです ↩