話題の React ベースフルスタックフレームワーク Remix のスタイリング事情を探ってみた

この記事は [株式会社サイバー・バズ Advent calendar 2021](https://qiita.com/advent-calendar/2021/cyberbuzz) 17日目の記事です。

16日目の記事は[@i12_yuya_i15](https://qiita.com/i12_yuya_i15)さんの[[AWS]V4署名を使ってOpenSearchにアクセスする](https://qiita.com/i12_yuya_i15/items/9506863a0401733c0028) 、
18日目の記事は[@kuririn_33](https://qiita.com/kuririn_33)さんの[ブラウザのタブを節約しつつ情報収集を高めるNotionの使い方入門](https://qiita.com/kuririn_33/items/408d1a2348628ad89ea0)です。

# 概要

今話題の React ベースフルスタックフレームワーク [Remix](https://remix.run/) の**スタイリング事情**について、

- **スタイルの設定方法はどんな感じなのか？**
- **スタイリングの外部フレームワーク（ライブラリ）にはどのくらい対応しているのか？**
    - *Sass には対応しているのか？*
    - *styled-components は使えるのか（CSS in JS に対応しているのか）？*

など、開発する上で気になる部分がどうなっているかまとめました。

※2021年12月17日時点での Remix のバージョンは `1.0.6` です。 

# スタイリングの主な設定方法

参考：[Remix | Styling](https://remix.run/docs/en/v1/guides/styling#styling)

主な方法は `links` という関数を用いて、
ページに `<link rel="stylesheet">` を追加することによって、スタイルを設定する形式です。

- CDN の場合
- CSS ファイルを直接インポートする場合

の2パターンありますが、どちらも共通した考え方です。

## URL を直接指定する

```tsx:URL直接指定
export function links() {
  return [
    {
      rel: "stylesheet",
      href: "https://unpkg.com/modern-css-reset@1.4.0/dist/reset.min.css"
    }
  ];
}
```

`href` に 呼び出したい CDN を記述します。
これを root で呼び出します。

```js
import { Links } from "remix";
// ...
export default function Root() {
  return (
    <html>
      <head>
        <Links />
        {/* ... */}
      </head>
      {/* ... */}
    </html>
  );
}
```

以上のようにすると、
`<Links />` で ``<link rel="stylesheet" href="https://unpkg.com/modern-css-reset@1.4.0/dist/reset.min.css">` が呼び出されます。

## CSS ファイルを直接インポートする場合

よく使うパターンはこちらになるかと思います。

```tsx:cssファイルインポートの例
import type { LinksFunction } from "remix";
import testStylesUrl from "~/styles/test.css";

export let links: LinksFunction = () => {
  return [
    { rel: "stylesheet", href: testStylesUrl },
  ];
};


export default function Index() {
  return (
    <div className="title">
      hoge
    </div>
  )
}
```

記述した css ファイルを import し、

```tsx
import testStylesUrl from "~/styles/test.css";
```

`links` を使ってエクスポートします。

```tsx:hrefにimport時の名前を記述する
export let links: LinksFunction = () => {
  return [
    { rel: "stylesheet", href: testStylesUrl },
  ];
};
```

後は、 TSX もしくは JSX 構文の中でクラス名を指定してあげるだけで OK です。

```tsx:クラス名titleの場合
export default function Index() {
  return (
    <div className="title">
      hoge
    </div>
  )
}
```

因みにこのとき、Remix の動作は

> 1. Copy the file to your browser build directory
> 2. Fingerprint the file for long-term caching
> 3. Return the public URL to your module to be used while rendering

>> 1. ブラウザのビルドディレクトリにファイルをコピーする
>> 2. 長期キャッシュのためにファイルをフィンガープリントする
>> 3. レンダリング時に使用するモジュールの公開 URL を返す

となっているようです。

# スタイリングに関する外部フレームワーク（ライブラリ）について

[CSS Ecosystem and Performance](https://remix.run/docs/en/v1/guides/styling#css-ecosystem-and-performance) に

> Remix supports many of them out of the box, but the frameworks that require direct integration with our compiler and expect Remix to automatically inject styles onto the page don't work right now.
>> しかし、コンパイラとの直接統合を必要とし、Remixが自動的にページにスタイルを注入することを期待するフレームワークは、今のところ動作していません。

と記述されている通り、現時点では一部動作しないものもあるようです。

## Sass について

**現時点で未対応**ですが、自身でスクリプトを設定することで導入が一応可能なようです。

参考：[Adding Sass to Remix - Better Dev](https://www.better.dev/adding-sass-to-remix)

Sass のサポートについては3週間ほど前から[issue で議論](https://github.com/remix-run/remix/issues/707)されているので、公式対応に期待したいですね。

## Tailwind CSS

対応しています。

[CSS Ecosystem and Performance](https://remix.run/docs/en/v1/guides/styling#css-ecosystem-and-performance) にて

> The two most popular approaches in the Remix community are route-based stylesheets and Tailwind. 

>> Remixコミュニティで最も人気のある2つのアプローチは、ルートベースのスタイルシートとTailwindです。

とされている程なので、現時点で Remix を開発する場合は Tailwind が相性良いようですね。

## styled-components

対応しています。

記述例などの詳細については [Remix | Styling # CSS-in-JS libraries](https://remix.run/docs/en/v1/guides/styling#css-in-js-libraries) をご覧ください。

# まとめ

Remix のスタイリングについては、
[Remix | Styling # CSS Ecosystem and Performance](https://remix.run/docs/en/v1/guides/styling#css-ecosystem-and-performance) に

> **`CSS support in Remix boils down to one thing: it needs to create a CSS file you can add to the page with <link rel="stylesheet">.`**

>> **RemixのCSSサポートは、`<link rel="stylesheet">`でページに追加できるCSSファイルを作成する必要がある、という一点に集約されます。** 

とあるように、現段階では **CSS を生成するフレームワーク中心**のサポートとなっています。
ただし、後半で

> **`All this is to say that we're still researching how best to integrate and work with the frameworks that require compiler integration.`**

>> **つまり、コンパイラの統合を必要とするフレームワークとどのように連携させるのがベストなのか、まだ研究中なのです。**

とまとめられていることや、
2021年12月17日時点でも styled-compontent を始めとした **CSS in JS のランタイム型フレームワークもサポートしている**ことから、
**スタイル設定の方法を限定しない方針で進んでいる**ことが伺えます。

まだまだ活発な更新が進められているので、どのような方向に進んでいくのか見守りつつ、
本記事を書くに辺り Remix を初めて導入してみたところ**「現段階でも普通に開発できるな」という感触**だったので、
Remix を使った開発が盛んになっていくことにも期待したいと思います。