こんにちは、フロントエンドエンジニアのやなぎ(@apple_yagi)です。
PR TIMESではフロントエンドのスタイリングライブラリにEmotionを使用していましたが、4ヶ月ほど前からCSS Modulesへの移行作業を開始しました(移行の経緯などについては別エントリーで紹介する予定なので、本エントリーでは割愛させていただきます)。その際にhappy-css-modulesを使用してCSS Modulesの型定義を生成する選択を取りました。
しかし、happy-css-modulesには一つ改善したい点がありました。本エントリーではその点を解消するためにhappy-css-modulesに機能追加をし、実際にプロダクトで使った話を紹介します。
happy-css-modulesについては以下の記事にわかりやすくまとまっています。

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

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

また、CSSファイルの名前を変更した際に、名前を変更する前の型定義ファイルが残ってしまうという問題もあり、そのファイルを削除するのにも手間がかかっていました。
実装した機能
outDirというオプションを以下のPull Requestで実装しました。このオプションを使用することで型定義ファイルを任意のディレクトリに出力することができるようになります。
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 に生成され、コンポーネントディレクトリをクリーンに保つことができます。


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

