Next.js 13 の App Routerでvanilla-extractを動作させる
やりたい事
Next.js 13 の App RouterではServer Components が利用される。
Server Components で vanilla-extract
が動作するかどうかの確認を行う。
ちなみに公式ドキュメントだとClient Componentsでのみサポートとなっている。
他のJSランタイムが必要なCSS in JSと同じ扱いというのが不思議だったので実際に試してみる事にした。
新規プロジェクト作成
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も有効にしておきたい。
必要なpackageをインストール
vanilla-extract
を導入していく。
npm install @vanilla-extract/css
Next.jsで vanilla-extract
を使う為に必要なpackageも追加。
npm install -D @vanilla-extract/next-plugin
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.appDir
を true
は本来不要のハズなのだが、これがないと動作しなかった。
サンプル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で一応動いている事が確認出来た。
Server Componentsでvanilla-extractを使っていくかどうか?
結論自分は辞めておこうと思っています。
理由は下記の2点です。
1. Next.jsの公式ドキュメントがClient Componentsでのみサポートと記載している点
The following libraries are supported in Client Components in the app directory:
Server Componentsで動作確認は取れましたが、こう書いてあるという事は一部の機能が動かない等の可能性があります。
experimental.appDir
を true
にしなければならないから
2. この設定はApp Routerが安定版になった今となっては不要な設定のハズですが、これがないとvanilla-extract
は動作しません。
これはissueとして報告されています。
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
を利用しても良いかもしれません。
代わりに何を使うべきか?
App RouterでServer Componentsを使っていくなら、CSS in JSは避けてCSS Modulesが無難だと思います。
https://zenn.dev/keitakn/scraps/49eb2616e82eb9 で進めている個人開発ではTailwind CSSを使いましたが、商用コードでデザインの制約などがある場合はCSS Modulesが最も無難な選択かもしれません。
仕事で進めている案件はFigmaのデザインを忠実に再現する必要があるのでCSS Modulesを使おうと思います。