webpackerの導入・設定メモ

自分用メモ。以下について書いています。

- webpacker導入
- React・Sassの導入・設定
- エントリーファイルの変更
- rails serverとwebpackの起動

##webpacker導入

###インストール

Gemfileに以下を記述し、インストール

```ruby:Gemfile
gem 'webpacker', github: "rails/webpacker"
```
```
$ bundle install
```

Rakeタスクでwebpackerを確認。

```
$ bin/rake -T | grep webpacker

Running via Spring preloader in process 1179
rake webpacker                          # Lists all available tasks in Webpacker
rake webpacker:check_binstubs           # Verifies that webpack & webpack-dev-server are present
rake webpacker:check_node               # Verifies if Node.js is installed
rake webpacker:check_yarn               # Verifies if Yarn is installed
rake webpacker:clobber                  # Remove the webpack compiled output directory
rake webpacker:compile                  # Compile JavaScript packs using webpack for production with digests
rake webpacker:install                  # Install Webpacker in this application
rake webpacker:install:angular          # Install everything needed for Angular
rake webpacker:install:elm              # Install everything needed for Elm
rake webpacker:install:react            # Install everything needed for React
rake webpacker:install:vue              # Install everything needed for Vue
rake webpacker:verify_install           # Verifies if Webpacker is installed
rake webpacker:yarn_install[arg1,arg2]  # Support for older Rails versions
```

webpackerをインストール。

```
$ rails webpacker:install
```
上記コマンド後、以下ディレクトリ・ファイルが追加される。

- app/
    - javascript/
        - packs/
            - application.js
- config/
    - webpacker.yml
    - webpack/
        - development.js
        - environment.js
        - production.js
        - test.js
- node_modules/
- postcssrc.yml
- babelrc
- yarn.lock
- package.json


## ReactとSassの導入・設定

### React

#### 導入

以下コマンドでReactをインストール

```
$ rails webpacker:install:react
```

`app/javascript/packs/hello_react.jsx`ファイルが生成される（サンプルファイル）


#### 設定

`javascript_include_tag`を`javascript_pack_tag`に変更

```erb:application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>SampleWebpack</title>
    <%= csrf_meta_tags %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

```

`app/javascript/packs/application.js`に`hello_react`ファイルをimport

```js:app/javascript/packs/application.js
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb

console.log('Hello World from Webpacker')

import './hello_react'
```


### Sass

#### 導入

`app/javascript/`に、`stylesheets/application.scss`を作成。

```css:app/javascript/stylesheets/application.css
body {
 color: red;
}
```

#### 設定

`stylesheet_link_tag `を`stylesheet_pack_tag `に変更

```erb:application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>SampleWebpack</title>
    <%= csrf_meta_tags %>

    <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

```

エントリーファイルにSassファイルをimport

```js:app/javascript/packs/application.js

/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb

console.log('Hello World from Webpacker')

import './hello_react'
import '../stylesheets/application'

```

### 確認

適当にcontrollerを作成

```
$ rails g controller static index
```

webpackとrails serverを起動（後で一つのコマンドで実行できるように設定）

```
$ rails s
```

```
$ bin/webpack-dev-server
```

"hello_react.js"の内容とSassの指定が反映されていればOK

<img width="891" alt="スクリーンショット 2017-11-26 11.30.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/126897/8eb2345f-b9d2-ea9c-06bb-740124081b88.png">

##エントリーファイルの変更

Sassをjavascriptディレクトリ内に配置するのが気持ち悪く、エントリーポイントを変えたい。（初期設定は`app/javascript/packs`がエントリー）

`webpacker.yml`を変更

```yml:webpacker.yml
default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_output_path: packs

↓↓↓↓　以下に変更

default: &default
  source_path: app/client
  source_entry_path: entry
  public_output_path: packs
```

`webpacker.yml`の変更に合わせ、`app/javascript/`の構成も以下のように変更

- app/
    - client/
        - entry/
            - application.js
        - javascript/
            - hello_react
        - stylesheets/
            - application.scss


rails serverを再起動し、"Hello World from Webpacker"や"Hello React"と表示されればOKです。

## rails serverとwebpackの起動

現状だとrails serverとwebpack dev serverを別々に実行しているためめんどくさい。

foremanを追加

```ruby:Gemfile
group :development do
  gem 'foreman'
end
```
```
bundle install
```

ルートディレクトリにProcfileを作成。
foremanでサーバーを立ち上げると、ボート番号は5000となるため、railsコマンドで3000を指定。

```ruby:Procfile
rails: rails s -p 3000
webpacker: ./bin/webpack-dev-server
```

foreman実行

```
$ foreman start
```

※package.jsonにscriptを記述し、`yarn start`でも良いと思ったが、rails serverがうまく停止できなかったので見送り。

## 最後に

間違っている箇所などあれば、コメントいただけると幸いです。