CSS Modules を置き換えようと思うに至ったときの課題点

4 min read

背景

技術スタックの一新で CSS Modules で記述していた部分を CSS in JS に置き換えた。

いずれにしても React コンポーネントも書き換える必要があり、そのまま CSS Modules を利用する大きなメリットはなかったため、再考の余地があった。

CSS Modules とは

CSS Modulesは、JS ファイルから CSS ファイルを import して利用する技術。

スタイル定義は通常の CSS と同様の記述のため、学習コストは低く、.component__T09hDのようなクラス名を自動生成してくれるため、クラス名の競合を防げるような特徴がある。

書き方

JS ファイルから CSS を import して、コンポーネントの className に CSS のクラスに該当する変数を指定することでスタイルが適用される。

/* styles.css */
.component {
  color: red;
}
// Component.jsx
import styles from "./styles.css";

const Component = () => {
  return <div className={styles.component}>Component</div>;
};

課題

CSS Modules を利用して感じた課題感は以下の通り。

  • 近い将来、非推奨になる可能性がある
    css-loader の CSS Modules はメンテナンスモードになっている
    webpack-contrib/css-loader: Interoperability across tools and support plain JS modules imports
    • アーキテクチャのリプレイス後に再びリプレイスを前提になることは避けたい
  • コンポーネント側でクラス名が間違っていてもエラーが発生しない
    • これまではパッケージを利用してstyles.css.d.tsを自動生成して補完やエラーが分かるようにしていた
  • スタイルの優先度に保証がない
    .red {
      color: red;
    }
    .blue {
      color: blue;
    }
    
    <div className={cx(red, blue)} />
    
    上記のようなケースでどちらが適用されるか分からない
  • 動的な CSS 操作がしづらい
    CSS クラスをマルチクラスとして切り替える必要がある

開発状況における課題としては以下の通り。

  • CSS ファイルと JS ファイルが別なため、管理コストがかかる
  • コンポーネントのスタイルをページによってカスケードする必要があった
    • React コンポーネント(CSS Modules)と HTML + CSS が共存した環境だった
      カスケードするためにクラス名の衝突を回避するハッシュ設定を外し、CSS 設計で名前衝突は回避していた
    • それでは CSS Modules のメリットを捨ててしまう

まとめ

そもそも CSS Modules を利用したクラス名が衝突しないというメリットを活かせていなかった。また、過去の資産を完全に活かしきることも難しく、全面的に React コンポーネントを利用したコンポーネント開発になることから CSS in JS の選択へ踏み切った。