Rails & React のフロントエンド環境構築⑴ webpacker で複数のエントリポイントを用意し、ページ毎に必要なアセットを分ける

# はじめに
WEBアプリケーションを構築する際、ActiveRecordやフォームビルダーが便利でよくRailsを使います。
多くの場合はやはり、フロントエンドはjQueryをjavascriptのライブラリを組み合わせて活用することでそれなりのアプリケーションを作れてしまいますが時に、メンテナンス性を考慮するとReact.jsなどのフロントエンドフレームワークを採用したいページもあります。

この記事では、そういう時に、`出来るだけRailsのレールに乗せられるところは乗せながら、フロントエンドは必要に応じて使い分けるために`、`webpackerを使って特定のページに合わせて必要なアセットファイルを管理する方法` をまとめした。

# 前提
## バージョン
Rails 5.2系
Webpacker 4系

## webpack のディレクトリ設定

```yml:config/wepacker.yml
default: &default
  source_path: frontend
  source_entry_path: packs
  public_root_path: public
  public_output_path: assets/packs


```

こうすると、プロジェクト直下の `frontend` ディレクトリ内にjsやcssを配置して
`frontend/packs` 配下にエントリポイントとなるファイルが配置されます。

ビルドしてまとめられたファイルは、プロジェクト直下の`public/assets/packs`に配置されます。

# 実装
上記の構成ですと、webpackerは、`packs` 配下に配置されたファイルに各ビルドするアセット情報を書き込んだファイルを元にビルドしますので、packs配下にページ毎に使うファイル（エントリポイントとなるファイル）を配置して、Rails側では 個別にレイアウトテンプレートを用意して、アセットファイルも読み込むことにします。

## ファイル構成
```
frontend/                                                                                                                                     
├── javascripts                      
│   ├── application.js                                        
│   ├── document_connection          
│   │   ├── quotation.tsx            
│   │   ├── transaction_application.tsx                                    
│   │   └── transaction_application_components                             
│   │       ├── applicant_preview.tsx
│   │       ├── contents_preview.tsx
│   │       ├── header_preview.tsx
│   │       ├── opening_sentence_preview.tsx
│   │       └── title_preview.tsx
│   ├── interface
│   │   └── transaction_application.ts
│   ├── uikit-icons.min.js
│   └── uikit.min.js
── packs
│   ├── application.js
│   └── document_connection
│       ├── quotation
│       │   └── edit.js
│       └── transaction_application
│           └── edit.js

└── stylesheets
    ├── application.scss
    ├── document
    │   ├── base.scss
    │   ├── edit.scss
    │   ├── quotation.scss
    │   └── transaction_application.scss
    ├── paper.css
    └── uikit.min.css
```

## エントリポイントファイル
pack配下に読むこむファイルをincludeしていきます。
ここで、このページはjqueryで、別ページではReactで切り分けたり、cssフレームワーク適用外のページを作ったりできます。

```js:frotend/packs/document_connection/quotation/edit.js

/* libs from npm */
import $ from 'jquery';
import {} from 'jquery-ujs';

/* componets & css framework */
import '../../../javascripts/application';
import '../../../javascripts/uikit.min';
import '../../../javascripts/uikit-icons.min';
import '../../../javascripts/document_connection/quotation';

/* styles */
import '../../../stylesheets/application';
import '../../../stylesheets/document/quotation';
import '../../../stylesheets/document/edit';
```

## ビルド結果(manifest.json)
ビルドするとエントリポイントごとにファイルがビルドされています。


```json:public/assets/packs/manifest.json
・・・
  "entrypoints": {
    ...
    "document_connection/quotation/edit": {
      "css": [
        "/assets/packs/css/document_connection/quotation/edit-cb0543fd.css"
      ],
      "js": [
        "/assets/packs/js/document_connection/quotation/edit-de73f1e5c60ea77dbcee.js"
      ],
      "css.map": [
        "/assets/packs/css/document_connection/quotation/edit-cb0543fd.css.map"
      ],
      "js.map": [
        "/assets/packs/js/document_connection/quotation/edit-de73f1e5c60ea77dbcee.js.map"
      ]
    },
...
    }
  }
}

```

`frotend/packs/document_connection/quotation/edit.js`
を配置するとjsとcssをそれぞれ生成し、Rails側では以下のようにアクセスできます


```
    <%= stylesheet_pack_tag("document/document_connection/edit.css") -%>
    <%= javascript_pack_tag("document/document_connection/edit.js") -%>
```


## レイアウトファイル
```erb:layout/something_page.html.erb
<!DOCTYPE html>

<html lang="ja">
  <head>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_pack_tag("document/document_connection/edit.css") -%>
    <%= javascript_pack_tag("document/document_connection/edit.js") -%>
  </head>

  <body>
    <%= yield %>
  </body>
  <script type="text/javascript">
  </script>
</html>


```

# 最後に
やはりRailsに慣れている人なら、Railsのレールに乗っかる方が開発スピードも落ちませんということでフロントエンドも必要に応じて適切な技術を選択していきたいところです。

今回はフロントエンドからRailsへの連携を扱いましたが逆に、Reactを使うとRailsからどうやってデータを渡すのかということも課題となってきます。次回はその辺もまとめてシェアできればと考えています。

最後まで読んでいただきありがとうございました！！