ひよっこエンジニアの雑多な日記

なんとかWeb系のエンジニアをやっています。

【Rails】Webpackerを導入してモダンなJavaScriptをRailsで使う

今回はWebpackerの導入について書いていきます。
内容的には手垢つきまくりの内容ですが、地味に体系的にまとまっているものがなかったのでまとめてみました!

やりたいこと

Webpakcer導入

RailsでモダンなJSフレームワークなどを利用する際にはWebpackerを導入して行きます。
WebpakcerはRails5.1以降からrails newの段階から導入できるようになっています。
またWebpackerはyarnに依存しているためyarnをインストールしておく必要があります。
今回はrails newからではなく、途中のプロジェクトからWebpakcerを導入していきます。

yarnインストール
https://yarnpkg.com/lang/ja/docs/install/#mac-stable

Railsプロジェクトの作成

$ rails new webpacker_sample --skip-turbolinks

turbolinksはjavascriptで画面を実装している際に思わぬ落とし穴になりがちなので入れないようにします。
Railsプロジェクトでまず実行するコマンド周りを実行しておきます。

$ bundle install --path vendor/bundle
$ rails db:create

Webpakcerの導入

Gemfileにwebpackerをインストールするように記載します。
ついでに必要なくなる子達も消しておきます。

# 追記
gem 'webpacker', '~> 3.5'

# 削除
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'

基本的にフロントエンド周りのライブラリはnode_module経由で利用するようにしたいので、sassやcoffeeは削除しておきます。

Gemfileを削除したらbundle installします。
bundle installが完了したら、webpackerをインストールします。

$ rails webpacker:install

インストールが完了するとconfig配下にwebpackerの設定ファイル、app配下にjavascriptディレクトリが生成されます。

rails newのタイミングでwebpackerを導入するとこの工程が不要になります。

Webpackerの設定を調整する

初期の状態だとapp/javascriptjavascriptしか使えないん?という感じのディレクトリ名なので、わかりやすいディレクトリ名に変更します。
config/webpakcer.ymlを修正することで対応することができます。

default: &default
  source_path: app/frontend # 変更
  source_entry_path: packs
  public_output_path: packs
  cache_path: tmp/cache/webpacker

この修正を加えた後にapp/javascriptディレクトリをapp/frontendにリネームしておきます。
またapp/frontend/配下にjavascriptsというディレクトリを作成して、その配下にapplication.jsを作成します。

app/frontend/packs/application.jsはwebpackのビルドの取りまとめを行うファイルとして扱います。

スタイルシートや画像も読み込めるようにする

スタイルシートと画像を保存するためのディレクトリを作成しましょう。
app/frontend/stylesheetsapp/frontend/imagesというディレクトリを作成しておきます。
stylesheets配下にはapplication.scssというファイルを作成しておきましょう。

ディレクトリとファイルが作成できたら、諸々の読み込みができるように app/frontend/packs/application.jsに追記します。

import 'stylesheets/application';
import 'javascripts/application';
require.context('../images', true, /\.(png|jpg|jpeg|svg)$/);

設定したjavascriptをviewで読み込めるようにする

javascriptの読み込みとstylesheetの読み込みをできるようにします。

<%= stylesheet_pack_tag 'application', media: 'all' %>
<%= javascript_pack_tag 'application' %>

stylesheet_link_tagstylesheet_pack_tagjavascript_include_tagjavascript_pack_tagに変更します。

設定できているか確認する

viewを作ってみてWebpackerの設定がうまくいっているか確認します。

$ rails g controller pages top

次にrails serverとwepack-dev-serverを立ち上げます。

$ rails s
$ bin/webpacker-dev-server

Webpakcerを使うとbin/webpakcer-dev-serverを実行する必要が出てきます。
rails sとwebpacker-dev-server二つをいちいち立ち上げるのが面倒な場合はforemanを導入するとコマンド一つで立ち上げられるようになります。
https://github.com/ddollar/foreman

コマンドをうったらページ確認のためにブラウザでhttp://localhost:3000/pages/topにアクセスしてみましょう。
問題なくアクセスできれば設定はうまくいっています。

もう少し実感できるようにするためにapp/frontend/javascripts/application.jsapp/frontend/stylesheets/application.scssを編集してみます。

alert('テスト'); // 追記
// 追記
h1 {
  color: red;
}

すると画面にアラートが表示されタイトルが赤く表示されると思います。

f:id:kimuraysp:20180615145956p:plain

rails-ujsを導入する

rails-ujsはdeleteやputといったrequestを飛ばすために必要なライブラリです。
app/assets配下を読み込まないようにしたためrails-ujsが効かなくなってしまっているので導入し直します。

$ yarn add rails-ujs

まずはyarnでrails-ujsをインストールします。
インストールができたらapplication.jsでrails-ujsの読み込みを行います。

// 追記
import Rails from 'rails-ujs';
Rails.start();

ここまで設定することでモダンなJavaScriptRailsで扱えるようになります。

最後に

これでVueでもReactでもなんでもござれです。 ただreact-routerやvue-routerといったクライアントサイドルーティングとRailsの相性が悪い(経験則)ので、SPAにするときはRailsにはAPIに徹してもらうのが一番そうです。