かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

React create-react-app したプロジェクトで stylus を使いたい

React のプロジェクトを作る時に create-react-app とても便利です。
しかしWEBアプリを作ると時に避けて通れないのが CSS
create-react-app のデフォルトではプレーンなCSSなので、コンポーネントごとにCSSを書けるとはいえチョット面倒です。せっかくなので慣れている stylus を `create-react-app で作成した React アプリで使えるようにしたメモ。

TL;DR

CSS Modules や create-react-app-stylus、npm script で stylus を監視させる方法でも実現できるのですが、 eject して webpack の config を弄る方法です。 (create-react-app の webpack の設定を見たかったという面もあり)

1. npm run eject で設定を取り出す

npm run eject を実行すると、create-react-app でよしなにしてくれていた設定が取り出されて自分で設定をカスタマイズできるようになります。

2. stylus をインストール

stylus を使うためにパッケージをインストールします。
css-loaderpostCSS などは既にインストールされているので stylusstylus-loader だけでOK

$ yarn add stylus stylus-loader

3. webpack の設定

webpack の設定は /config/webpack.config.js にあります。
webpack.config.jsmodule.exports している関数内で return されているオブジェクトが webpack の設定です。この中に stylus の設定を追加します。

module.exports = function(webpackEnv) {
  // 中略
  return {
    // 中略
    module: {
      strictExportPresence: true,
      rules: [
        // 中略
        {
          oneOf: [
            // 中略
            // "postcss" loader applies autoprefixer to our CSS.
            // "css" loader resolves paths in CSS and adds assets as dependencies.
            // "style" loader turns CSS into JS modules that inject <style> tags.
            // In production, we use MiniCSSExtractPlugin to extract that CSS
            // to a file, but in development "style" loader enables hot editing
            // of CSS.
            // By default we support CSS Modules with the extension .module.css
            // ... CSS の設定

            // Stylus
            {
              test: /\.styl$/,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  getLocalIdent: getCSSModuleLocalIdent,
                },
                'stylus-loader'
              ),
              sideEffects: true,
            },

          ],
        },
      ],
    },
 };
};

postCSS で prefix を付けたりする設定は定義されている getStyleLoaders (cssOptions, preProcessor) でよしなしにしてくれるので、これの第二引数に stylus-loader を渡します。
webpack では css-loader で処理される CSS ファイルは削除すべきではない副作用を持つファイルだとされているようなので、sideEffects: true を設定し勝手に削除されないようにします。

c.f. 2018 年の tree shaking | Kabuku Developers Blog

4. stylus が使えるようになっているかテスト

/src ディレクトリ内に適当な stylus ファイルを作成し、アプリで stylus ファイルを import して動作しているかテストします。

/src/stylus/App.styl

.app
  color: #91d2e1

/src/App.js

import React from 'react';
import './stylus/App.styl';

function App() {
  return (<div className="app">星宮いちご</div>);
}
export default App;

react アプリを起動

$ yarn start

stylus の CSS が反映されていて、 stylus ファイルを変更したら hot-reload されるようになっていればOKです。

ポエム

たぶんナウいやり方だと元に戻せない eject するのではなく CSS Module を使った方法にするのかなーと思いました。
ただ eject することによってイケてるフレームワークのフロント開発の設定がどうなっているのか学べるよい機会にもなったように思います。
何となく、gulp は秘伝のタレになるから時代は webpack とかチョット前によく見聞きしてましたが、結局 webpack も設定は秘伝のタレになってて、フレームワークでは設定を触らずに済む方法に進化したっぽい。という印象をもちました。
結局自分で環境をつくるなら webpack にしろ、 gulp にしろプロジェクトに合うものを選んで、秘伝のタレを作るしかなさそうだなーと感じました。(まる。


[参考]

ダンベル何キロ持てる? (1) (裏少年サンデーコミックス)

ダンベル何キロ持てる? (1) (裏少年サンデーコミックス)