14
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TypeScriptを使うと、emotionを使うためにbabel pluginがいらなくなる理由を調べてみた

Last updated at Posted at 2023-02-01

TypeScript 4.1以上だと、emotion/reactを動かすために必要な設定はこれだけになります。

tsconfig.json
{
  "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でcompilerOptionsjsxreact-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から呼び出すことができるようになりました。

tsconfig.json
{
  "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をコンパイルする時に使う関数を選択しているようです。

参考

14
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?