RemixにCSS Modulesを導入する

公開日: 

はじめに

リリースノート

https://github.com/remix-run/remix/releases/tag/remix%401.16.0

公式ドキュメント

https://remix.run/docs/en/main/guides/styling#css-modules

Remix のバージョン 1.16.0 から CSS Bundling が stable 化され、CSS Modules などがデフォルトで使えるようになりました。

数行追加するだけなのでとても簡単です。

使用するパッケージのバージョンは記事執筆時点で以下の通りです。

  • @remix-run/css-bundle@1.17.1
  • @remix-run/dev@1.17.1
  • @remix-run/node@1.17.1
  • @remix-run/react@1.17.1
  • @remix-run/serve@1.17.1

CSS Modules の導入

公式ドキュメントに従って導入していきます。

https://remix.run/docs/en/main/guides/styling#css-modules

CSS のバンドリングはデフォルトで行われるようになったので、@remix-run/css-bundleというパッケージを使用して、 バンドリングされた CSS ファイルの参照を取得して links 関数に追加するだけです。

terminal
npm install @remix-run/css-bundle
sample.tsx
import { cssBundleHref } from '@remix-run/css-bundle';
import type { LinksFunction } from '@remix-run/node'; // or cloudflare/deno

export const links: LinksFunction = () => {
  return [
    ...(cssBundleHref ? [{ rel: 'stylesheet', href: cssBundleHref }] : []),
    // ...
  ];
};

cssBundleHrefの参照はroot.tsxなどで行うと良いらしいです。

これだけで CSS Modules が使えるようになっています。

app/components/button/styles.module.css
.root {
  border: solid 1px;
  background: white;
  color: #454545;
}
app/components/button/index.js
import styles from './styles.module.css';

export const Button = React.forwardRef(({ children, ...props }, ref) => {
  return <button {...props} ref={ref} className={styles.root} />;
});
Button.displayName = 'Button';

落とし穴

モジュールを 再 export している場合、CSS ファイルがバンドルに含まれない

具体的にはindex.jsなどで

index.js
export * from './Button.jsx';

このような感じで再 export していると、Button.jsxファイルの中で

Button.jsx
import styles from './styles.module.css';

このように CSS ファイルを参照していても、このファイルは現状バンドル化されないため、スタイルが適用されません。

これは公式ドキュメントにも書いてあることなんですが、注意は必要です。

https://github.com/evanw/esbuild/issues/1370

どうすれば良いか

この不具合は esbuild の問題で、esbuild のバージョン0.17.7で修正されています。 しかし、現状の Remix の最新バージョンである0.17.1では esbuild の0.17.6、つまりまだ不具合が修正されていないバージョンを使用していないためこの不具合が起きていると思われます。また、ワークアラウンドとして、

export { Button } from './Button.jsx';

このように名前付きで再 export することで CSS ファイルがバンドルに含まれるというものがあります。なので現状の解決策としては

  • Remix に esbuild0.17.7が採用されるのを待つ
  • 名前付きの再 export を採用する

の 2 択になるかなと思います。

最後に

とても簡単に CSS Modules の導入ができました。

まぁ自分は連携するライブラリのバージョンがずれていることに気が付かずに 1 日溶かしたんですけどね

では

Bye