Make IT Advent Calendar 2019 24日目の記事です。
今年も危うくクリぼっちになりかけましたが、サークルの仲間とクリパすることになりました。
皆様も良いクリスマスをお過ごしください。
今年は、マイCSSブーム到来というやつです。5日目にもCSS関連の記事を投稿しました。
ゼミやインターンでSCSSを使っていますが、少し前からstyled-componentsに興味が湧いたので、勉強がてらどっちも書いてみようという旨です。
差分が発生する箇所について、コードを書いた感想を述べていくだけですので、実行環境だけ欲しい方は 環境 > リポジトリ(github) をクリックして git clone
してください。
環境
-
リポジトリ(github)
- 投稿時現在では、矢印アイコン・メニューボタン・クレジットカードコンポーネント(作り途中)が含まれています。
- 言語・ライブラリ
- typescript(v3.7.2)
- react(v16.12.0)
- storybook/react(v5.2.8)
- scss(v4.13.0)
- styled-components(v4.4.1)
- 実行環境
- macbook pro 2015 catalina
- google chrome
- エディタ
- visual studio code
- vscode plugin
- vscode-styled-components
- テンプレートリテラル内でcssの補完が効きます
- color highlight(他にオススメあればご教授ください)
- テンプレートリテラル内でカラーコードの背景に色が出なかったので導入しました
- vscode-styled-components
差分
webpack.config.js
module.exports = {
/* 一部省略 */
module: {
rules: [
{
test: /\.(ts|tsx)?$/,
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/react"]
}
},
"ts-loader"
]
},
{
test: /\.css?$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.scss?$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
url: false,
sourceMap: true,
importLoaders: 2,
modules: true
}
},
{
loader: "postcss-loader",
options: {
sourceMap: true,
plugins: [require("autoprefixer")({ grid: true })]
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new TypedCssModulesPlugin({
globPattern: "src/**/*.scss"
})
],
/* 一部省略 */
};
scssのために4つのloaderを通しています。おかげでconfigが縦に長い!
autoprefixerしか使っていないので良いですが、今後を考えるとpostcss.config.jsとして別ファイルにした方が良いですね。
TypedCssModulesPlugin はscss保存時、自動でd.tsを生成します。dropbox製というのが好きです。
私は、フォルダをコンポーネント名にして、中にindex.tsxを作成する方法を使います。
これは、コンポーネントに関係する style.scss, style.d.ts, react custom hooksをまとめてフォルダ内に置けるので気に入っています。
module.exports = {
/* 一部省略 */
module: {
rules: [
{
test: /\.(ts|tsx)?$/,
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/react"],
plugins: ["babel-plugin-styled-components"]
}
},
"ts-loader"
]
}
]
},
/* 一部省略 */
};
スッキリしました。
autoprefixer・TypedCssModulesPluginの役割は、styled-componentsが全て担ってくれます。
babel-plugin-styled-components について、こちらの記事が参考になりました。
reset.css
// for SCSS
import 'reset-css';
// for styled-components
import React from 'react';
import { Reset } from 'styled-reset';
const App = () => (
<>
<Reset />
<div>Hello world!</div>
</>
);
SCSSでは shannonmoeller/reset-css を使用します。
styled-componentsでは zacanger/styled-reset を使用します。
ソースコード比較(buttonコンポーネント)
See the Pen menu button scss by haduki1208 (@haduki1208) on CodePen.
マウスホバーでアニメーションするボタンです。
これをstyled-componentsで置き換えます。
See the Pen menu button styled by haduki1208 (@haduki1208) on CodePen.
scssがなくなったことでフォルダ内がスッキリしますが、scssの内容がtsxに移動するのでファイルが縦に長くなります。
私はvscodeのエディタを分割してtsxとscssを並べながらコードを書くので、辛さがあります。
↓こんな感じ
解決策として、
- atomic designを意識してコンポーネントを小さくしていく
- style.tsx のようなファイルを用意してstyledの要素を宣言する
を考えました。基本的に1番の方法を実践していきたいと思います。
おわりに
趣味で何かコーディングするとき、このリポジトリ(github)を使っていこうかなと思っています。
storybookも始めて導入してみたのですが、どんなコンポーネントがあるか一通り見れるので便利です。
scss(css)で培ってきた技術がそのままstyled-componentsに活用できるため、
新規プロジェクトはstyled-componentsだったらいいなぁと思っています。