Rails5.1ではAsset Pipeline捨てたほうがいいらしいので捨ててみた

## まえがきのまえに
この記事は [Wanoグループアドベントカレンダー](https://qiita.com/advent-calendar/2017/wano-group) の25日目です． ***25日目です．***
クリスマスはまだ終わってない．終わってないったら終わってない．サンタさんからプレゼントももらってないし．

## まえがき
Rails 5.1で，従来のAsset PipelineによるJavaScriptやCSSなどのアセット管理手法に加えて，フロントエンド界隈で有名らしいWebpack（正確にはRailsによるラッパーであるWebpacker）によるアセット管理手法が提供されるようになった．

Asset Pipelineによるアセット管理ではCoffee Scriptsへの依存や野良gemによるJSライブラリ管理の限界などの問題が生じるらしい．
それを問題と感じる場合や，ReactやVueなどのナウでヤングなJSライブラリを使いたいナウでイケイケなヤングはWebpackerの導入を検討しても良いだろう．

また，Webpackerは基本的にAsset Pipelineとの共存を考えて作られている．
しかしこれらはほぼ同一の機能を提供するため，片方に寄せたいと考えるのは割と自然な発想である（たぶん）．
そこで本稿ではRails 5.1でWebpackerを導入し，Asset Pipelineを捨てる方法について調べて実践した内容をまとめる．

また，個人的にVue.jsを使ってみたかったために合わせてVue.jsを導入している．
そこらへんに興味のない人は適宜読み飛ばしたりしてほしい．

## 環境
- OS X Yosemite
- Ruby 2.4.3
- Rails 5.1.4

RailsのWebpacker周りは導入されたばかりで色々と議論されていて色々と変更が多いため，（割といつもそうだけど）バージョンは特に気にする必要があることに注意．

## 前準備
Webpackerはyarnに依存しているから，これをインストールする必要がある．
macの場合はhomebrewとかを使うのが楽でいい．

```
$ brew install yarn
```

## Railsの導入
いつものやつ．とはいえRailsに慣れていない僕みたいな人もいるだろうから一応書く．まず，

```
$ cd /path/to/working/dir
$ rbenv local 2.4.3
$ gem install bundler
$ bundle init
```
でテキトーなディレクトリにGemfileを用意する．（別にrbenvを使う必要はない．）

次にGemfileをこんな感じに編集する．

```Ruby:Gemfile
gem 'rails', '5.1.4'
```

保存したら以下のコマンドを打ってrailsを導入する．
ここで，**rails newのオプションがWebpackerの導入やAsset Pipelineから脱却を図る上で重要になってくる**ので注意して実行しよう．

```
$ bundle
$ rails new . --skip-coffee --skip-turbolinks --skip-sprockets --webpack=vue
```

ディレクトリは他のディレクトリを指定してもいい．ただこの場合僕にはディレクトリ構成がキレイじゃなくなるように見えるから，カレントディレクトリに直接導入するようにしている．
カレントディレクトリに導入する場合，Gemfileを上書きするか聞かれるけど，これはそのまま上書きして良い．

また，その他のコマンドラインオプションは上に書いたとおり，Webpackerの導入やAsset Pipelineからの脱却にとって非常に重要なものである．それぞれこんな感じのオプションである．

- `--skip-coffee` : CoffeeScriptsからの脱却．CoffeeScriptsを使いたい場合は指定しなくてよい．
- `--skip-turbolinks` : turbolinksからの脱却．評判が悪かったりVue.jsと相性が悪かったりするらしいので，僕はturbolinksを外した．SPAとかやらないならつけててもよかったりするらしい．
- `--skip-sprockets` : Sprocketsからの脱却．Asset Pipelineでよしなにやってる中身はだいたいこいつが担っているイメージ．Webpackerに色々任せる場合は多分いらないんじゃないかな．
- `--webpack=vue` : Webpackerの導入．Rails 5.1では `rails new` のときにこれを指定するとWebpackerが導入できて楽ちん．また，`=react|angular|vue` とすることでReact, Angular, Vueを導入できる．

バージョン管理をしている場合は（`rails new`ではデフォルトでGitによるバージョン管理が始まるので利用しよう），ここでcommitするといいと思う．

## ディレクトリ構成をいい感じにしたりする
デフォルトでwebpackerで管理されるファイルは `/app/javascripts` に入れることになっている．
一方で `/app/assets` にもJSやCSS，imageなどのファイルが入っていてなんだか気持ち悪い．
どうせAsset Pipelineは使わないので， `/app/assets` は消してしまおう．

```
$ rm -rf app/assets
```

次に，webpackerで他のアセットも管理しようとしている以上， `/app/javascripts` という名前は少々不適切だ．
適当にリネームしてディレクトリを掘って，適切な状態にしていく．

```
$ mv app/javascripts app/frontend
$ cd app/frontend
$ mkdir stylesheets
$ touch stylesheets/application.css
$ mkdir javascripts
$ touch javascripts/application.js
$ mkdir images
$ touch images/.keep
```
なお， `/app/frontend` ではなく `/frontend` にする人も多いそう．ここらへんはお好みで．

## railsの設定をいい感じにする
### webpackerの設定を変更する
前節でrailsがデフォルトで作成するディレクトリを変更したため，そのままではrailsはファイルを読んでくれない．
`config/webpacker.yml` で以下のようにすることでディレクトリの変更に追従してもらう．

```yml:config/webpacker.yml
 default: &default
-  source_path: app/javascript
+  source_path: app/frontend
```

### .jsや.cssを読み込む
`app/frontend/` 以下にファイルを作ったはいいものの，それを読み込めなければそれはただのゴミだ．
`app/frontend/pack/application.js` でこれらを読み込むようにする．

```JavaScript:app/frontend/pack/application.js
+import '../javascripts/application';
+import '../stylesheets/application';
+
+require.context('../images', true, /\.(png|jpg|jpeg|svg)$/);

 console.log('Hello World from Webpacker')
```

### rails-ujsを入れる
Railsが用意してくれているjsであり，form関連でお世話になることも多い（らしい）`rails-ujs`．
Asset Pipelineだとデフォルトでこれを読み込んでくれるが，webpacker（というよりnpm OR yarn）だと読み込んでくれないし容易もしてくれていない．
だから自分で入れよう．

```
$ yarn install rails-ujs
```

導入したらこれを読み込むようにしよう．

```JavaScript:app/frontend/javascripts/application.js
+import Rails from 'rails-ujs';
+
+Rails.start();
```

余談だが，Rails 5.1でjQueryへの依存が廃止されたため， `jquery-ujs` が廃止され `rails-ujs` に書き換わったらしい．

### 余計なassetを生成しないようにする
`rails g controller Hoge` とかでコントローラを作るとき，デフォルトではAssetを色々作成してくれる．
でも多分いらないから，デフォルトでは作らないようにする．

```Ruby:config/application.rb
   class Application < Rails::Application
    config.load_defaults 5.1
    config.generators do |g|
      g.assets false
    end
  end
```

多分これでWebpackerを導入し，Asset Pipelineから脱却ができる．
とはいえrailから多少なりとも外れる行為ではあると思うので，ちょっと注意しながら開発を進める必要があるかもしれない．

~~一番まずいのは僕もこの環境を整えてさあこれからやっていくぞというところなので本当に大丈夫なのかわからないところ~~

ではここまで．