TypeScript 4.1以上だと、emotion/reactを動かすために必要な設定はこれだけになります。
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react"
}
}
旧JSXランタイムで使っていた時は、@emotion/babel-preset-css-prop
を別途インストールして使っていたのですが、これが不要になりました。
このライブラリは内部でbabel pluginを使っているようです。
冒頭の設定をするだけでemotionが使えるということで、tsconfigがどう関係しているのか?というところから分かっていなかったので調べてみました。
旧ランタイムの場合
React 17から新ランタイムが導入されました。
以前は、以下のように
In
import React from 'react';
function App() {
return <h1>Hello World</h1>;
}
Out
import React from 'react';
function App() {
return React.createElement('h1', null, 'Hello world');
}
import React
を書いておいて、babelによってReact.createElementに変換していました。
しかし、emotionを使っている場合は旧ランタイムのときから、emotionで定義されているjsx
を使ってJSXをコンパイルしていました。
In
const Link = props => (
<a
css={{略}}
{...props}
/>
)
Out
import { jsx as ___EmotionJSX } from '@emotion/react'
(一部略)
const Link = props =>
___EmotionJSX(
'a',
_extends(
{
css: _ref
},
props
)
)
TypeScript 4.1 以降
TypeScript 4.1でcompilerOptions
のjsx
にreact-jsx
が追加されました。
これは、新ランタイムを使えるようにするための機能で、以下のように変換されるようになります。
これにより、import React
を手で書く必要がなくなっています。
In
export const HelloWorld = () => <h1>Hello world</h1>;
Out
import { jsx as _jsx } from "react/jsx-runtime";
import React from 'react';
export const HelloWorld = () => _jsx("h1", { children: "Hello world" });
さらに、jsxImportSource
で、jsx
の関数を呼び出すモジュールを指定することができるようになりました。
先程、
import { jsx as _jsx } from "react/jsx-runtime";
と出力されていたところが、tsconfigに以下のように設定することで、jsx
の関数を@emotion/react
から呼び出すことができるようになりました。
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react"
}
}
これによって、babel pluginが不要になったようです。
jsx pragmaについて
ちなみにbabelの設定ができないような環境では、元々、以下のようにjsx pragmaを使う方法もあります。
/** @jsx jsx */
import { jsx } from '@emotion/react'
このjsx pragmaもJSX fragmentsをコンパイルする時に使う関数を選択しているようです。