Closed6

Next.js 13 の App Routerでvanilla-extractを動作させる

keitaknkeitakn

やりたい事

Next.js 13 の App RouterではServer Components が利用される。

Server Components で vanilla-extract が動作するかどうかの確認を行う。

ちなみに公式ドキュメントだとClient Componentsでのみサポートとなっている。

他のJSランタイムが必要なCSS in JSと同じ扱いというのが不思議だったので実際に試してみる事にした。

https://nextjs.org/docs/app/building-your-application/styling/css-in-js

keitaknkeitakn

新規プロジェクト作成

npx create-next-app@latest で新規プロジェクトを作成する。

対話式のプロンプトへの回答は以下のようにした。

npx create-next-app@latest
Need to install the following packages:
  create-next-app@13.4.3
Ok to proceed? (y) y
✔ What is your project named? … next-vanilla-extract
✔ Would you like to use TypeScript with this project? … Yes
✔ Would you like to use ESLint with this project? … Yes
✔ Would you like to use Tailwind CSS with this project? … No
✔ Would you like to use `src/` directory with this project? … Yes
✔ Use App Router (recommended)? … Yes
✔ Would you like to customize the default import alias? … No

ポイントは Use App Router をyesにする事(既にデフォルトでyesになっている)TypeScriptも有効にしておきたい。

keitaknkeitakn

必要なpackageをインストール

vanilla-extract を導入していく。

npm install @vanilla-extract/css

Next.jsで vanilla-extract を使う為に必要なpackageも追加。

npm install -D @vanilla-extract/next-plugin
keitaknkeitakn

next.config.js の変更

以下のように変更する。

const {
  createVanillaExtractPlugin
} = require('@vanilla-extract/next-plugin');
const withVanillaExtract = createVanillaExtractPlugin();

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
};

module.exports = withVanillaExtract(nextConfig);

experimental.appDirtrue は本来不要のハズなのだが、これがないと動作しなかった。

サンプルCSSの追加

src/styles/styles.css.ts というファイルを新規作成する。

import { style } from '@vanilla-extract/css';

export const container = style({
  padding: 20,
  backgroundColor: 'pink',
  fontSize: 50,
  color: '#fff',
});

src/app/page.tsx を変更

以下のように変更する。

import { container } from '@/styles/styles.css';

export default function Home() {
  return (
    <main className={container}>
      <div className={container}>ねこ、こねこ</div>
    </main>
  )
}

動作確認

npm run build を実行後 npm run start を実行 http://localhost:3000 にアクセスを行う。

問題なく動作している事を確認した。

App Router利用時はServer Componentsが利用されるのでServer Componentsで一応動いている事が確認出来た。

keitaknkeitakn

Server Componentsでvanilla-extractを使っていくかどうか?

結論自分は辞めておこうと思っています。

理由は下記の2点です。

1. Next.jsの公式ドキュメントがClient Componentsでのみサポートと記載している点

https://nextjs.org/docs/app/building-your-application/styling/css-in-js

The following libraries are supported in Client Components in the app directory:

Server Componentsで動作確認は取れましたが、こう書いてあるという事は一部の機能が動かない等の可能性があります。

2. experimental.appDirtrue にしなければならないから

この設定はApp Routerが安定版になった今となっては不要な設定のハズですが、これがないとvanilla-extract は動作しません。

これはissueとして報告されています。

https://github.com/vanilla-extract-css/vanilla-extract/issues/1087

We're going to follow up with the Next team about how to deal with these issues going forward. We're having to reach into private Next internals to make VE work currently which is the cause of these issues.

Will report back once they've responded.

とあるので何か根深い問題があるのかもしれません。

私はバグを踏みたくないので今回は vanilla-extract を諦めますが今後正式サポートがされるなら vanilla-extract を利用しても良いかもしれません。

keitaknkeitakn

代わりに何を使うべきか?

App RouterでServer Componentsを使っていくなら、CSS in JSは避けてCSS Modulesが無難だと思います。

https://zenn.dev/keitakn/scraps/49eb2616e82eb9 で進めている個人開発ではTailwind CSSを使いましたが、商用コードでデザインの制約などがある場合はCSS Modulesが最も無難な選択かもしれません。

仕事で進めている案件はFigmaのデザインを忠実に再現する必要があるのでCSS Modulesを使おうと思います。

このスクラップは2023/05/24にクローズされました