型安全な CSS Modules?「vanilla-extract」

kimizuy

はじめに

絶賛、CSS Modules を使ったプロジェクトで作業している kimizuy です。最近、vanilla-extract という良さげな CSS フレームワークの 1.0.0 がリリースされたので、本記事では CSS modules と vanilla-extract を比較して、この新しいフレームワークの利点について書きたいと思います。

CSS Modules で作業するときの辛さ

CSS Modules はローカルスコープがデフォルトの CSS フレームワークです。CSS の名前衝突の問題を回避できて、これ自体はとても強力な機能です。

ただ問題なのは、作業する際に CSS ファイルでクラスネームを追加したり変えたりしてもコンポーネント側でエラーが出ないので気づけないこと、これに尽きます。

つまり、コンポーネント側でクラスネームが間違っていてもエラーが出ないため、実行するまでスタイルが当たっているかどうか気づくことができません。必然的にスタイルを確認する作業のコストが大きくなります。

また、VSCode & 拡張機能を入れることで、クラスネームのインポート時の補完を行っていますが、エディタ機能にかなり依存している状態はあまり健全ではないなと個人的に思っています。これに付随して CSS ファイルを保存しないとエディタが変更を検知できないので、それまで正しいクラスネームでの補完に頼れないのも地味に面倒です。

vanilla-extract とは

簡単に説明すると TypeScript で書ける CSS Modules です。.css.tsというファイルに React の style prop と同様の記法でスタイルを書いていきます。

export const exampleStyle = style({
  backgroundColor: vars.color.brand,
  fontFamily: vars.font.body,
  color: 'white',
  padding: 10
});

このフレームワークの大きなメリットは以下の 2 点です。

  • TypeScript の静的解析に頼れる
  • ビルド時に静的な CSS ファイルを生成するため CSS-in-JS よりもパフォーマンスに優れる

開発者の 1 人である Mark Dalgleish は CSS Modules の作者でもあります。そのためか、このフレームワークでは上記で挙げたような CSS Modules のデメリットを TypeScript によって克服したことがわかります。

開発元が Codesandbox を用意してくれているので、簡単に vanilla-extract を試すことができます。

デメリット

型安全に書ける vanilla-extract ですが、ちょっとしたデメリットもあります。

.css.ts というファイルに分けて管理する必要がある

CSS-in-JS のようにコンポーネントファイルにスタイル層を作って、一つのファイルで管理して扱うような書き方はできません。

style prop 記法

プロパティはキャメルケース、値は基本的に string で指定する必要があります。なので 通常の CSS の書き方で慣れている方は戸惑うかもしれません。CSS Modules などから移行する際にも一手間必要になります。

参考

以下の記事では CSS フレームワークに emotion/core を選ぶ過程について詳細に書かれています。TypeScript による静的解析のしやすさという点で本記事と共通しているため参考にさせていただきました。

レシピサービスのフロントエンドに CSS in JS を採用した話

さいごに

TypeScript の型の恩恵が受けられる CSS Modules として、上記のようなデメリットに目をつぶれば、かなりの好印象を個人的に持っています。
これから CSS Modules で書こうと思っている人は vanilla-extract もかなり有力な候補になるのではないでしょうか。
以上、本記事が誰かのお役に立てれば幸いです。

Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています

弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?

もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!

求人応募してみる!

kimizuy

投稿者 Yamasaki Kimizu

React, Redux, TypeScript プロジェクトでフロントエンド領域を担当。個人でも Next.js アプリの開発をしています。日課はRSSで取得した技術記事を読むこと、最近の関心は Core Web Vitals です。将来はでかい犬が飼いたいです。