happy-css-modulesに機能追加して実際にプロダクトに適用した話

  • URLをコピーしました!

こんにちは、フロントエンドエンジニアのやなぎ(@apple_yagi)です。

PR TIMESではフロントエンドのスタイリングライブラリにEmotionを使用していましたが、4ヶ月ほど前からCSS Modulesへの移行作業を開始しました(移行の経緯などについては別エントリーで紹介する予定なので、本エントリーでは割愛させていただきます)。その際にhappy-css-modulesを使用してCSS Modulesの型定義を生成する選択を取りました。

しかし、happy-css-modulesには一つ改善したい点がありました。本エントリーではその点を解消するためにhappy-css-modulesに機能追加をし、実際にプロダクトで使った話を紹介します。

happy-css-modulesについては以下の記事にわかりやすくまとまっています。

mizdra's blog
コードジャンプ可能な CSS Modules を実現する happy-css-modules の紹介 - mizdra's blog 弊社では React で CSS を書くための手法として CSS Modules を全面的に採用しています。そこで CSS Modules を使った開発をより快適にするために、「happy-css-modules」...
目次

happy-css-modulesで改善したかった点

従来のhappy-css-modulesでは生成したCSS Modulesの型定義をそのCSSファイルがあるディレクトリと同じ場所にしか生成できませんでした。

1つのディレクトリにCSS Modulesのファイルとコンポーネントのファイル、型定義のファイルが存在している

そのため、1つのディレクトリに複数のCSSファイルが存在している場合、型定義ファイルにディレクトリが埋め尽くされ、視認性が低下していました。

1つのディレクトリに6つのCSS Modulesのファイル、コンポーネントファイル、型定義ファイルが存在している

また、CSSファイルの名前を変更した際に、名前を変更する前の型定義ファイルが残ってしまうという問題もあり、そのファイルを削除するのにも手間がかかっていました。

実装した機能

outDirというオプションを以下のPull Requestで実装しました。このオプションを使用することで型定義ファイルを任意のディレクトリに出力することができるようになります。

GitHub
Add support for `--outDir` option by apple-yagi · Pull Request #270 · mizdra/happy-css-modules I created a Pull Request because I wanted the outputFolder option available in typed-css-modules to also be present in happy-css-modules. Could you please revie...

outDirオプションは元々 typed-css-modules に存在しており、このオプションが前述した問題点を解決できるものであると私は知っていました。そのため、PR TIMESのCSS Modules移行の開始時期にPull Requestを出していました。結果としてマージするまでに4ヶ月という期間がかかりましたが、無事マージすることができて嬉しいです。happy-css-modulesをメンテナンスしていらっしゃるmizdraさんに感謝です(何度もレビューしていただき、ありがとうございました🙏)。

プロダクトに導入

outDirオプションはPull Requestをマージした当日にリリースされたv3.2.0に入っており、次の日にPR TIMES内で使用するためにhappy-css-modulesのバージョンアップを行いました。

outDirオプションを使用する際はtsconfigのcompilerOptionsのrootDirsを変更する必要があります。rootDirsの変更方法はアプリケーションのディレクトリ構造によって異なりますが、PR TIMESでは以下のようにしています。

{
  ...
  "scripts": {
    // generated/hcm というディレクトリに出力
    "hcm": "hcm 'src/**/*.module.css' -o generated/hcm",
    "hcm:w": "hcm -w 'src/**/*.module.css' -o generated/hcm",
    ...
  },
  ...
}
{
  ...
  "compilerOptions": {
    "rootDirs": ["src", "generated/hcm/src"]
  },
  ...
}

このようにすることで型定義ファイルは generated/hcm に生成され、コンポーネントディレクトリをクリーンに保つことができます。

コンポーネントディレクトリに型定義ファイルはない
generated/hcmディレクトリに型定義ファイルが存在している

monorepo環境下における注意点

PR TIMESではpnpmを利用したmonorepo環境で開発しており、上記の対応だけでは別packageのコンポーネントをインポートした際に tsc で以下のようなエラーが発生します。

このエラーは別パッケージのtsconfigで設定されているrootDirsの設定を読み込めず、CSS Modulesの型定義が見つからないため、発生しています。今回の場合、利用する側のパッケージにとっては別パッケージのtype errorは関係ないため(そのパッケージ内でtypecheckが保証されていれば)、利用する側のパッケージにCSS Modulesの型定義を追加し、エラーを抑えました。

declare module '*.module.css' {
  const styles: Record<string, string>;
  export = styles;
}

これにより、別パッケージのコンポーネントをインポートした時はグローバルの型定義が使われ、ローカルのパッケージ内ではhappy-css-modulesで生成した型定義が使われます。

まとめ

PR TIMESでは現在、EmotionからCSS Modulesへの移行作業に取り組んでいます。正直なところCSS Modulesに移行することによりEmotionの時よりもスタイリングをするDeveloper Experience(DX)が低下していることを実感しています。しかし、happy-css-modulesなどのライブラリにより一定のDXは獲得できているとも思っています。このようなOSSを開発・メンテナンスしてくれている開発者には感謝しかなく、今回のように私自身も何かしら貢献していきたいと思います。

We are hiring!

フロントエンドエンジニアを含む各種ポジションでの採用を進めています!興味があればぜひご応募ください。

あわせて読みたい
株式会社PR TIMES
02.開発部 の求人一覧 - 株式会社PR TIMES 株式会社PR TIMESが公開している、02.開発部 の求人一覧です
  • URLをコピーしました!

この記事を書いた人

株式会社PR TIMES 開発本部 フロントエンドエンジニア

目次