13
8

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.

React/TS環境にemotion入れてみる

Last updated at Posted at 2019-06-15

はじめに

前回に引き続きReact/typescriptの環境構築やっていきます。
相変わらず拙い点が多いですがおおめに見てください。
前提となる環境は前回と同じです。

その1: React/TypeScript環境構築編

今回は、スタイル関係の気になったライブラリを導入していきます。
タイトルにある通りemotionなるものを試して見ることにします。

ひとまず今回の目標は簡単にスタイルを当てるところまでにします。

何故emotionを選んだか

emotion: introduction

確たる理由はありません。
何やら後発のライブラリで、いろいろな書き方ができるそう。
折角いじるんだし、とりあえず使ったことが無いものを使ってみよう的なモチベーションです。

styled-componentsと比較してもそれなりに人気があることがわかります。

スクリーンショット 2019-06-15 21.59.07.png

emotion導入の前に1

今回の導入はその1の続きから行っていきます。

ので、v0.1.0としてtagをつけて公開します。以下tag付けのコマンドです。
別にリリースするわけでもないのでブランチ切るだけでいいのですが、しっかり使ったことのない機能だったので使ってみます。

$ git tag -a 'v0.1.0' -m 'react/typescript環境構築編'
$ git push origin v0.1.0

手元で試したい方は、以下リポジトリをクローンしてv0.1.0タグをチェックアウトしてください。
$ git clone https://github.com/savacan/sample-react-ts.git
$ cd sample-react-ts
$ git checkout -b (ブランチ名) refs/tags/v0.1.0
$ yarn install

babelを入れる

以下の項で行うコマンド操作はプロジェクトルートです。

前回の環境構築編ではbabelを導入していませんでした。
どうやらドキュメントを読んでいる限り、babelを入れたほうが良さそうなので、導入します。

まず必要なものを入れていきます。
$ yarn add -D @babel/core @babel/preset-env @babel/preset-react babel-loader

次にbabelの設定ファイルを作ります。

$ code .babelrc

.babelrc
{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
    ]
}

次にwebpack.config.jsにbabel-loaderを使うように設定を入れます。
この時、loaderは下から実行されるそうなので、順番に注意してください。

webpack.config.js
module.exports = {
 // 省略
   module: {
      rules: [
        {
          test: /\.tsx?$/,
          use: [
            {loader: 'babel-loader'},
            {loader: 'ts-loader'}
          ]
        }
      ]
    },
 // 省略
}

この状態でyarn devで画面が見れたらbabel導入おっけーです。

@emotion/core

reactで使う場合こいつを入れたらとりあえず使えそう。ということでまずドキュメントを読みます。

………

どうやら、css属性にstyleオブジェクトを指定する形で使うようです。
ひとまず導入して見ましょう。

まずinstallします。

$ yarn add @emotion/core

そして使ってみます。
componentディレクトリを作って、hogeコンポーネントを作って試してみます。

$ mkdir src/component
$ code src/component/hoge.tsx

つまずきその1

早速インポートして………あれ?

スクリーンショット 2019-06-16 0.37.40.png

ということで、少し調べてみました。
どうやらmodule解決のところで問題がおきていたようなので、moduleResolutionオプションをnodeにしてみると解決しました。これを機にtsconfig.jsonを以下のように変更。

tsconfig.json
{
    "compilerOptions": {
        "outDir": "./dist",
        "sourceMap": true,

        "module": "ESNEXT",
        "target": "ESNext",
        "jsx": "react",

        "strict": true,
        "noUnusedLocals": true,
        "noImplicitReturns": true, 

        "moduleResolution": "node",

        "typeRoots": [
            "node_modules/@types"
        ]
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "node_modules"
    ],
}

* moduleResolutionオプションはデフォルトでnodeというような記述を見かけたのですが、明示的に書くことで変わるのでしょうか……?

つまずきその2

気を取り直して、hogeコンポーネントを書いていきます。

hoge.tsx
/** @jsx jsx */
import * as React from 'react'
import {css, jsx} from '@emotion/core'

const Hoge: React.FC = () => {
    return (
        <div css={css({color: 'red'})}> Hoge is red! </div>
    )
}

export default Hoge;

そしてHogeコンポーネントを表示するようにindex.tsxを書き換えます。

index.tsx
import * as React from 'react';
import { render } from 'react-dom';
import Hoge from './components/hoge';

const Main: React.FC = () => (
    <div>
        <div>Hello, Happy World!</div>
        <Hoge></Hoge>
    </div>
);

render(<Main />, document.getElementById('root'));

ひとまずこれで $ yarn dev すると、下の画面が表示されるはずです。

スクリーンショット 2019-06-16 1.23.15.png

これで、一旦導入は出来ました。
しかし、このままだとコンポーネントの先頭行に毎回同じコメントを入れねばなりません。
ということで、@emotion/babel-preset-css-propを導入してみます。

$ yarn add -D @emotion/babel-preset-css-prop

でインストールして。.babelrcに追記します。

.babelrc
{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react",
        "@emotion/babel-preset-css-prop"
    ]
}

そして、hoge.tsxから先頭のコメントを外してみます。
すると、@emotion/coreからインポートしているjsxが未使用としてコンパイルで弾かれてしまいます。
ので、以下のようにまとめてインポートするように変更します。

hoge.tsx
import * as React from 'react'
import * as emotion from '@emotion/core'

const Hoge: React.FC = () => {
    return (
        <div css={emotion.css({color: 'red'})}> Hoge is red! </div>
    )
}

export default Hoge;

これで画面を確認してみると………あれ?

スクリーンショット 2019-06-16 1.31.36.png

Hoge is red が赤くなってないですね。
開発者ツールで確認してみると。

スクリーンショット 2019-06-16 1.34.59.png

css属性が解釈されていないですね。
どうやら、emotionのjsx関数ではなく、Reactの方でtsxを解釈しているようです。

これまで行った設定を冷静に思い出してみると、webpackさんが、まずts-loaderを呼び出して次にbabelさんを通るはず。なら問題はts-loaderか。ということで、もう一度tsconfigのドキュメントを読むことに。

どうやら、compilerOptionのjsxでreactを指定しているのが良くないようです。
ここでjsxを解釈してしまっているよう。
なので、jsxの解釈を後回しにするようjsxにpreserveを指定してみました。

スクリーンショット 2019-06-16 1.45.27.png

うまくいきました……

ただ無知なだけですが、新しいものをいじるときはやっぱり時間がかかるなぁと。

そして、どうやらimportをまとめてやる必要もなさそうです。
emotion/babel-preset-css-propが、必要なところに自動でimportを入れてくれるようで、Hogeコンポーネントは以下のように書けます。

hoge.tsx
import * as React from 'react';
import {css} from '@emotion/core';

const Hoge:React.FC = () => {
    return (
        <div css={css({color: 'red'})}>Hoge red!</div>
    )
}

export default Hoge;

まとめ

ここまでお疲れ様でした。

やっと@emotion/coreの導入だけが終わりました。
tscofing,webpack,babelの設定は本当にちゃんと勉強しようと反省しました……

今回はある程度長くなってきてしまったのでここまでにします。
次回はemotionを使って少しコンポーネントを書いたり、使い心地や挙動を確かめようと思います。

ここ間違ってるぞ、動かねぇぞ、という指摘お待ちしております。
以下リポジトリ、今回の進捗はadd-emotionブランチを切ってあります。

13
8
2

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
13
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?