Next.jsのTypeScript環境にEmotionを入れたい

この記事は最終更新日から1年以上が経過しています。

Next.js 12.2でEmotionが標準でサポートされているためこちらの記事は、Next.js 12.2以下の場合になります。(2022/11月追記)

Tailwind.cssで進めていたNext.jsのプロジェクトですが、複雑なアニメーションはやはり自前のCSSを書いた方が実装が速いということになり、Next.jsのTypeScript環境にEmotionをインストールしたので備忘録です。

まずNext.jsの公式サイトからこちらのリポジトリ(https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss-emotion#how-to-use)に飛びクローンしました。Next.jsにEmotionをinstallしたサンプルです。サンプルのpackage.jsonを眺めたところ@emotion/react @emotion/styledがinstallされていたので真似してinstallしました。

$ npm install --save @emotion/react @emotion/styled

ではstyleを記述します。

import React, { useState } from 'react';
import { css, jsx } from '@emotion/react'

export default function Header({}) {
  return (
    <div  css={css`padding: 10px;`}>test</div>
  );
}

エディタ上で「TS2322: Property 'css' does not exist...」とエラーだ出るのでtsconfig.jsonに下記を追記しました。

"compilerOptions": {
  "types": ["@emotion/react/types/css-prop"],
},

では起動します。

$ npm run dev

確認します。

うっ!

謎のエラーが出ていました。

css="You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."

attributeの部分にエラーが出るのが面白いですね!

もう一度、サンプルのpackage.jsonを眺めました。

なんとbabelがインストールされていました。TypeScriptだから入れたくないと反抗し色々試行錯誤(tsconfig.jsonのcompilerOptionsなど変えてみたり)をしたのですが、結局うまく行きませんでした。

やはり素直にbabelを入れることとしました。

$ npm install --save-dev @babel/core @emotion/babel-plugin

そして.babelrcを作成しました。

{
  "presets": [
    [
      "next/babel",
      {
        "preset-react": {
          "runtime": "automatic",
          "importSource": "@emotion/react"
        }
      }
    ]
  ],
  "plugins": ["@emotion/babel-plugin"]
}

では起動します。

$ npm run dev

おおお!

無事に出力されました。

素直になるのが大事だと思った夜でした。

ここまでお読みくださりありがとうございます。