はじめに
前回に引き続きReact/typescriptの環境構築やっていきます。
相変わらず拙い点が多いですがおおめに見てください。
前提となる環境は前回と同じです。
今回は、スタイル関係の気になったライブラリを導入していきます。
タイトルにある通りemotionなるものを試して見ることにします。
ひとまず今回の目標は簡単にスタイルを当てるところまでにします。
何故emotionを選んだか
確たる理由はありません。
何やら後発のライブラリで、いろいろな書き方ができるそう。
折角いじるんだし、とりあえず使ったことが無いものを使ってみよう的なモチベーションです。
styled-componentsと比較してもそれなりに人気があることがわかります。
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
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
次にwebpack.config.jsにbabel-loaderを使うように設定を入れます。
この時、loaderは下から実行されるそうなので、順番に注意してください。
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
早速インポートして………あれ?
ということで、少し調べてみました。
どうやらmodule解決のところで問題がおきていたようなので、moduleResolutionオプションをnodeにしてみると解決しました。これを機に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コンポーネントを書いていきます。
/** @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を書き換えます。
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
すると、下の画面が表示されるはずです。
これで、一旦導入は出来ました。
しかし、このままだとコンポーネントの先頭行に毎回同じコメントを入れねばなりません。
ということで、@emotion/babel-preset-css-prop
を導入してみます。
$ yarn add -D @emotion/babel-preset-css-prop
でインストールして。.babelrcに追記します。
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"@emotion/babel-preset-css-prop"
]
}
そして、hoge.tsxから先頭のコメントを外してみます。
すると、@emotion/coreからインポートしているjsxが未使用としてコンパイルで弾かれてしまいます。
ので、以下のようにまとめてインポートするように変更します。
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;
これで画面を確認してみると………あれ?
Hoge is red が赤くなってないですね。
開発者ツールで確認してみると。
css属性が解釈されていないですね。
どうやら、emotionのjsx関数ではなく、Reactの方でtsxを解釈しているようです。
これまで行った設定を冷静に思い出してみると、webpackさんが、まずts-loaderを呼び出して次にbabelさんを通るはず。なら問題はts-loaderか。ということで、もう一度tsconfigのドキュメントを読むことに。
どうやら、compilerOptionのjsxでreactを指定しているのが良くないようです。
ここでjsxを解釈してしまっているよう。
なので、jsxの解釈を後回しにするようjsxにpreserveを指定してみました。
うまくいきました……
ただ無知なだけですが、新しいものをいじるときはやっぱり時間がかかるなぁと。
そして、どうやらimportをまとめてやる必要もなさそうです。
emotion/babel-preset-css-propが、必要なところに自動でimportを入れてくれるようで、Hogeコンポーネントは以下のように書けます。
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ブランチを切ってあります。