Rails4アプリケーションへのWebpack導入


# About

Heroku上のRails4フロントエンドJSをいい感じにする活動の一環


## As-Is
- 多くのJSライブラリをRailsバインディングで使うRails4アプリ
- JSはasset pipelineで配信
- 新規JSライブラリ導入
	- Railsバインディングが用意されているか毎回調査
	- Railsバインディングのメンテのペースに制約される
		- セキュリティなどの問題解決が遅れることがある
- 今後はnpmでの導入前提での情報のほうが多そう

## To-Be

- npmモジュールの更新に追随し、Node.jsのエコシステムの恩恵をより享受できるようにする
- 最初の目標として、npmで導入したモジュールの動作をローカルとHerokuで確認する
- 既存JSコードベースの変更を最小限に留める

## 今回のスコープに入らないこと
- JSのローカル開発の効率化
- React関連の整理
- CSSの取り回し

## バージョン
- node: v4.1.2
- npm: 2.14.6
- Rails: 4.2.5

# bundleツールの選択

## Webpack or Browserify 

Google Trends

![Screen Shot 2016-09-29 at 3.04.14 PM.png](https://qiita-image-store.s3.amazonaws.com/0/281/c2eb0c2b-bcb0-c5f0-ece8-c2d995174836.png "Screen Shot 2016-09-29 at 3.04.14 PM.png")


とりあえずWebpackをつかってみる

- https://webpack.github.io/


# ローカルで動かす

## ディレクトリ構成
```
$ mkdir -p frontend/config/production frontend/src/javascripts
```



## package.json作成



```
$ npm init
$ npm install webpack --save
```

## npmモジュール追加


なんでもよいが、たとえば`autotrack`をインストールしてみる

- https://www.npmjs.com/package/autotrack

```
$ npm install autotrack --save
```



## scripts追加

Webpackを叩くscriptを登録する。



```package.json 
{
  "name": "YOUR-APP",
  "version": "1.0.0",
  "description": "== README",
  "main": "index.js",
  "directories": {
    "test": "test"
  },
  "scripts": {
    "webpack:deploy": "webpack -v --config frontend/config/production/webpack.config.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "autotrack": "^1.0.3",
    "webpack": "^1.13.2"
  }
}

```




## Webpackの設定


```frontend/config/production/webpack.config.js
module.exports = {
  entry: {
    app: './frontend/src/javascripts/app.js',
  },
  output: {
    path: './app/assets/javascripts',
    filename: "[name].bundle.webpack.js",
  },
}

```


## require/export
``` frontend/src/javascripts/app.js
autotrack = require('autotrack')
module.exports = [autotrack]
```



## ビルド

```
$ npm run webpack:deploy
```

`app/assets/javascripts`に`app.bundle.webpack.js`が生成される。
ファイルの存在を確認し、マニフェストから`require`ないし`require_tree`する。

```app/assets/javascripts/application.js 
//= require_tree .
```

## 動作確認

Railsサーバーを起動し、ブラウザのdevコンソールで見る

![Screen Shot 2016-10-13 at 10.24.18 AM.png](https://qiita-image-store.s3.amazonaws.com/0/281/e2cb8858-241b-df28-bd98-6cea8697e367.png "Screen Shot 2016-10-13 at 10.24.18 AM.png")




# Herokuで動かす
## scripts追加

先程追加したscriptをheroku上で起動させる`heroku-postbuild`を登録しておく（これに気づかずハマった）

- https://devcenter.heroku.com/articles/nodejs-support

```package.json
  "scripts": {
    "webpack:deploy": "webpack -v --config frontend/config/production/webpack.config.js",
    "heroku-postbuild": "npm run webpack:deploy",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

```



## Buildpack追加


webpackでのファイル生成がRailsのprecompileの前に行われるようにBuildpackの順番を調整する。

- https://devcenter.heroku.com/articles/buildpacks


```
$ heroku buildpacks:clear --app YOUR-APP
$ heroku buildpacks:set heroku/nodejs --app YOUR-APP
$ heroku buildpacks:add heroku/ruby  --app YOUR-APP
```

`app.json`で指定する方法もあるようだが試していない。




## Herokuへpush

```
$ git add package.json frontend
```

commitしてHerokuへpushする



## 動作確認
Herokuアプリを開き、ローカル同様にブラウザの開発者コンソールで確認



# 参考

- https://webpack.github.io/docs/tutorials/getting-started/
- http://crypt.codemancers.com/posts/2016-03-18-rails-webpack-heroku/

- http://qiita.com/dakatsuka/items/c815a27b9740c843bee0
- http://qiita.com/necojackarc/items/afa674ab10aafa9784eb