@emotion/core は @jsx jsx を書かなくても使える

CSS in JS系のライブラリの中では、[emotion](https://emotion.sh/docs/introduction)が一番好きです。

今まで、[`@emotion/core`](https://www.npmjs.com/package/@emotion/core)はJSX Pragma (`/** @jsx jsx */`)を書くのが必須と思っており、Reactに載せてるのにわざわざ[`emotion`](https://www.npmjs.com/package/emotion)の方を使っていました。

しかし、[`@emotion/babel-preset-css-prop`](https://emotion.sh/docs/@emotion/babel-preset-css-prop)を使えば、💩みたいなJSX Pragmaをいちいち書く必要なんてありませんでした。ほんと嬉しいので、共有しておこうと思い記事化しただけの記事です。

## Before

そもそもTypesScriptだから`tsx`なのに、`@jsx`と書かなければならないのは 🤮です。

```Greeting.tsx
/** @jsx jsx */
import React from 'react';
import { jsx } from '@emotion/core';

const Greeting: React.FunctionComponent = () => {
  return(
    <p css={{
      backgroundColor: 'hotpink'
    }}>
      Hello Statham
    </p>
  )
}
```

## After

[`@emotion/babel-preset-css-prop`](https://emotion.sh/docs/@emotion/babel-preset-css-prop)を追加 (`yarn add --dev @emotion/babel-preset-css-prop` ) して、`babel`のconfig or webpackの`babel-loader`のconfigにpresetsを追加するだけです。

自分のwebpack.config.jsの`babel-loader`の部分はこんな感じ。

```webpack.config.js
{
  test: /\.(j|t)sx?$/,
  exclude: /node_modules/,
  use: [
    {
      loader: 'babel-loader',
      options: {
        cacheDirectory: true,
        cacheCompression: true,
        babelrc: false,
        sourceType: 'unambiguous',
        presets: [
          ['@babel/preset-env', { useBuiltIns: 'usage', corejs: 3 }],
          '@babel/preset-typescript',
          '@babel/preset-react',
          '@emotion/babel-preset-css-prop',
        ],
        plugins: ['@babel/plugin-proposal-class-properties'],
      },
    },
  ],
},
```

そうすれば、もう何も`import`する必要はない。(`@emotion/core`とか長いので、それを書く必要すらないのも素晴らしい。)

```Greeting.tsx
import React from 'react';

const Greeting: React.FunctionComponent = () => {
  return(
    <p css={{
      backgroundColor: 'hotpink'
    }}>
      Hello Statham
    </p>
  )
}
```

### `css`に対する型定義も忘れずに

なんの定義もしないまま、ただHTMLタグに`css`だけ生やそうとすると、もちろんエラーが出る。

`Property 'css' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>'.ts(2322)`

この場合、どこでもいい (自分は`global.d.ts`にした) ので、`/// <reference types="@emotion/core"/>`この一文を追加しておく。

ref: https://github.com/emotion-js/emotion/issues/693#issuecomment-448088489

以上でDONE。さよならJSX Pragma。

## 何故今まで気がつかなかったのか。。。

そもそも、自分が使い始めた当初である昨年の秋冬には[ギリギリ存在しなかった](https://github.com/emotion-js/emotion/pull/1049)。

ただそれより、[Introductionのページ](https://emotion.sh/docs/introduction#react)にもっと大きく注意を引く感じで記載して欲しかった。。

まぁこれで、来年も快適なemotion lifeを送れそうです。

## 追記： `css` propsを使用している場合に、React component 間で子要素に css props を渡す方法

[ドキュメント曰く](https://emotion.sh/docs/css-prop#style-precedence)、コンポーネントに渡された`css` props は`className` props にコンバートされるようで、`className` props は `css` props の内容より優先度高く適用されるようです。

つまり、

```tsx
type Props = {
  className?: string
}

const Children: React.FunctionComponent<Props> = ({ className }) => {
  return (
    <div className={className} css={{ color: 'blue' }}>
      Children
    </div>
  );
};

const Parent: React.FunctionComponent = () => {
  return (
    <Children css={{ color: 'red' }} />
  );
};
```

このようにすると、`Children`の文字色は**赤**になります。
`Props`の型定義に`css`が必要ないのは、上述の通り global に `css` を定義したからです。

うーん、素晴らしい！使いやすいですね。

ただ少しあれなのは、`css`はグローバルに定義されているため、どんなコンポーネントにも付与できますが、そのスタイルが適用されるかは、コンポーネントの実装に`className` props を渡す実装が含まれているかに寄るところで、辛いです。😥