emotionの環境構築をおこなったところ、
TypeScript絡みの設定が案外手強かったので備忘録とさせていただきます。
ざっくり環境
React v17.0.1
typescript v4.1.3
@emotion/react v11.1.4
@babel/core v7.12.10
jsx属性認識しない問題
import { jsx } from '@emotion/react'
import { FooterContainer } from '../../../style/components/block/Footer'
export default function Footer() {
return (
<div css={FooterContainer}>
<p>Footer</p>
</div>
)
}
emotion v11においては、
上記のように jsx
をimportして、reactからやってくるjsxを使わない(reactを直でimportしない)記述となります。
しかし、早速問題が...
なんとか型定義をimportしているjsxの方に向かせたいですね。
そもそもreactのJSXの型定義はどこからきているのでしょうか?
答えはTypeScriptのコンパイルのオプションである jsxFactory
からきています。
https://www.typescriptlang.org/tsconfig/#jsxFactory
こちらはデフォルトでは React.createElement
になっています。
jsxFactory
をemotionのjsxで呼べるよう変更しておきます。
ちなみにトランスパイルをbabelに任せている場合、 "jsx": "preserve"
でOKです。
{
"compilerOptions": {
"jsx": "preserve",
"jsxFactory": "jsx",
...
}
これでエラーが解消されます。
別解:プラグマを使う
公式のドキュメントでは以下のようなコメントが差し込まれています。
/** @jsx jsx */
このコメントはプラグマというTSでサポートされている機能になります。
この機能は、ファイル毎にjsxFactoryを変更できる機能です。
こちらを追加するとエラーが解消されます。
/** @jsx jsx */
import { jsx } from '@emotion/react'
import { FooterContainer } from '../../../style/components/block/Footer'
export default function Footer() {
return (
<div css={FooterContainer}>
<p>Footer</p>
</div>
)
}
ただ、ファイル毎にプラグマを記述しないといけないのが微妙ですね。
わがまま
jsxを直で上書きしてしまうのはちょっと不安です。
毎度jsxを読まないといけないのもなんか微妙です。
もっといい方法があれば教えていただけると嬉しいです