こんにちは、 streampack の minsu です。
東京オリンピックが決まった時はまだまだ先だと思っていた2020年が来ましたね!あまり実感がないですが!

はじめに

ページごとに読み込まれるcssとjsを変更したいことがあるかと思います。
RailsでWebpacker利用時にページごとにcss,jsのスタイルを分ける方法をまとめました。

作業内容は次の通りです。

  • エントリポイントを複数作成する
  • ページごとに対応するエントリポイントを呼び出す

また、こちらの過去の記事の環境を使っています。
Docker + Rails + Reac

ファイル構成

Webpackerディレクトリ構成

Webpackerのconfigを見てみると
app/javascriptにjs,cssを
app/javascript/packsにエントリポイントを配置し
ビルド後のファイルはpublic/packsに格納されるようになっています。

config/webpacker.yml

default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_output_path: packs
...

さて現在のapp/javascriptディレクトリのファイル構成です。

app/javascript                                                                                                                                     
├── components           
│   └── users
│       ├── Edit.js
│       ├── Index.js
│       ...                                                                                  
├── packs
│   └── application.js 
└── src
    ├── js
    │   └── application.js 
    └── css
        └── application.css 

configの通りpacks/application.jsがエントリポイントとなります。
srcにはcss, jsファイルを、
componentsにはreact-railsgemを使っている関係でReactファイルを配置しています。

エントリポイント

application.js

var componentRequireContext = require.context("components", true);
var ReactRailsUJS = require("react_ujs");
ReactRailsUJS.useContext(componentRequireContext);

import "src/js/application.js";
import "src/css/application.css";

エントリポイントである packs/application.jsを見てみます。
上3行のcomponentsディレクトリのReactファイルをRails view側から呼び出すためのreact-railsの記述と
下2行のsrcのjs,cssファイルimportの記述があります。

ビルド後はこの情報を元にjs,cssがひとまとめのファイルとなります。
そのため、Rails側の下記コードでエントリポイントを指定する事で

application.html.erb

<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>

viewからReactファイルの利用と、
src/js/application.js,src/css/application.cssの読み込みを行えます。

viewからReactを利用するのに必要ですのでエントリポイント applicationは全てのページから共通で呼び出すようにします。

エントリポイント作成

本題ですがページごとに読み込まれるcssとjsを変更したい場合を考えます。
この場合、packs/application.jsのエントリポイントにimportを追加すると全てのページに反映されてしまい都合がよくありませんので、新たにエントリポイントをして必要なページから呼び出すようにします。

packs/users/index.js

import "src/js/index.js";
import "src/css/index.css";

index.html.erb

<%= javascript_pack_tag 'users/index' %>
<%= stylesheet_pack_tag 'users/index' %>

上記のようなエントリポイントを作成して必要なviewなどから呼び出す事で、
必要なページでのみスタイルを反映させることができます。

ファイル構成

app/javascript                                                                                                                                     
├── components           
│   └── users
│       ├── Edit.js
│       ├── Index.js
│       ...                                                                                    
├── packs
│   ├── application.js 
│   └── users
│       └── index.js
└── src
    ├── js
    │   ├── application.js 
    │   └── users
    │       └── index.js 
    └── css
        ├── application.css 
        └── users
            └── index.css

参考

https://github.com/rails/webpacker
https://github.com/reactjs/react-rails

元記事はこちら

webpacker でページごとにスタイルを分ける