Storybookはじめてみました。

NextJS + TailwindCSSの既存プロジェクトに追加

install

$ cd ./project_root
$ npx storybnook@latest init
$ npx run storybook

AddOn

$ npx storybook@latest add @storybook/addon-styling-webpack

これでstorybookにaddonを追加。
あとはコンソール出力に従えばtailwindcssを検知して
必要なパッケージを追加ロード。

アプリのCSSのエンドポイントをstorybookの設定ファイルに指定してくれます。
(サンプルではtailwind.cssを指定していますが、自分の場合当該パスにファイルがなかったので
../app/global.scssを指定しました。(アプリのCSSのエンドポイント))

Run storybook

$ npm run storybook

チュートリアルのサンプルとして./storiesディレクトリが作成され、その中にいくつかの
サンプル用コンポーネントが用意されいます。

これでとりあえず動きます。

ここで、./stories内のButtonをtailwindcssで置き換えてみましょう。
というチュートリアルが下記

Integrate Tailwind CSS and Storybook

なんですが、tailwind.config.ts./storiesが含まれていないためこのままだと動きません。


const config: Config = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './stories/**/*.{js,ts,jsx,tsx,mdx}', // これ追加
  ],

これでサンプルフォルダ内のコンポーネントに対してもtailwindcssのスタイルが
適用されるようになります。(tailwindcssは使われているクラスのみでビルドするため)

NextJSでApp Routerであれば本来はcomponentディレクトリにガンガンcomponent作りつつ
pagesディレクトリにルーティングに対応したページ用componentが定義される感じになるのかな?

とりあえずstorybook + tailwindcssで動きましたね。

ちょっと調べて・触って感じたStorybookメリット/デメリット

参考

メリット

  1. アプリケーションを起動しなくてもコンポーネントの確認・修正が可能
  2. 自然とpropsの指定、コンポーネントの切り出し、ロジックの分離が行われる

デメリット

  1. 言う程デメリットでもないかもしれないが、storybookの設定ファイルが増える
  2. デザイナがコンポーネント定義をガンガンやれるのがきっと理想なんだろうけど、TypeScriptの前提知識がそこそこ必要。

デザイナー1人、プログラマー1人みたいな小規模なプロジェクトであれば
コミュニケーションツールとしても良さそう。

人数が多くなってきたらコンポーネントの重複には注意したいところ。
あとこれはStorybookの話題とは離れるけど、コンポーネントの粒度をどうするか
(例としてAtomiDesignのような)方針があるといいかもしれない。

storiesファイルの書き方

公式にあったものを一部抜粋して確認してみる

import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
  title: 'Example/Button', // コンポーネントの名前で、スラッシュで階層を指定することも可能
  component: Button, // 対象コンポーネントを指定
  parameters: {
    // refs: https://storybook.js.org/docs/react/configure/story-layout
    // centered, fullscreen, paddedの3種類で、storyboardのプレビューでの表示方法
    layout: 'centered',
  },
  // refs:  https://storybook.js.org/docs/react/writing-docs/autodocs
  // autodocsタグを付けることで自動的にドキュメントを作ってくれる。
  // ドキュメントのテンプレートをmdxで定義とかもできるっぽいけど割愛
  tags: ['autodocs'],
  // More on argTypes: https://storybook.js.org/docs/react/api/argtypes
  // コンポーネントのPropsをStorybookのUIから操作する時のコントロールを決める。
  // 下記の例だとbackgroundColorにカラーピッカーを表示するように指定している。
  // 無論、指定したコンポーネントに存在しないPropsを指定するとエラーになる。
  // ※[key: string]:anyとかあるとなんでも入るけど。
  argTypes: {
    backgroundColor: { control: 'color' },
  },
} satisfies Meta<typeof Button>;

export default meta;
type Story = StoryObj<typeof meta>;

// refs: https://storybook.js.org/docs/react/writing-stories/args
// ここより下に、各ボタンのストーリーというか、使われ方というかそういうのを書いていく。
// 僕個人としては不便に感じるんだけど、ここで指定したものが優先的にUIでは上部に表示されるっぽい。
export const Primary: Story = {
  args: {
    primary: true,
    label: 'Button',
  },
};

export const Secondary: Story = {
  args: {
    label: 'Button',
  },
};

どういう粒度でコンポーネントを分割するべきか、は勉強中で
何かピンときたら別途でまとめます。

本題とは外れますがTailwindcssのメリット・デメリットについて考える

この記事を書き始めたとき、「流行ってるっぽいから」というのみの理由で
TailwindcssをStorybookと連携し、コンポーネントのスタイリングに利用できるように
ここまでの文章を書いていました。

しかし、書きながら

  1. CSSプロパティと1:1になっているクラス名をひたすら覚える必要がある
  2. それをひとつづつクラスにあてていくので、当然クラス宣言が非常に長くなる
  3. 既存のクラス名を複数組み合わせて定義するので、同じスタイルにしたい別要素に対して再利用が面倒
    • tailwindcssのクラス名を列挙したものをオブジェクトに定義しておいて、展開するようにすればできるだろうけど面倒だよね?
  4. (ReactとかVue使っていれば)CSS書いてたデザイナーもjsx触る必要が出てくる

などなど気になってきました。

他の人が何故採用したのか、どのように運用しているか、みたいなのググってみたら
同じように感じてる人はもちろんいて、デメリットとして挙がってるもののメリットとしては

  1. 予めクラスが定義されており、コードに宣言的に付与していくので開発スピード・メンテナンス性の向上
    • クラス名を考える必要も減る、ということらしい。
  2. デザインシステムとして、コンフィグ・テーマの提供が容易。一貫したものになりやすい
  3. 対応したクラスが用意されていてレスポンシブ対応が容易

ここで挙げられてる内容に関して、一旦なるほど~となりつつも

1.に関して感じたこと

それがメリットならインラインスタイルで良くない!?
クラス名は大切だし考えるのコストかもしれないけど、じゃあ仮でもいいからつけるとか。。。
これは自分のやってきた範囲が規模が小さいから感じることかもしれない。

class属性の中身が横にひたすら長くなっていくのは結構ストレスに感じている。(慣れなのか?)

2.に関して感じたこと

これは確かにありがたいかも。ただ、scssでthema.scssでも今のところ困ったことがない。
設定ファイルうんぬん調べてて、個人的にはprefixつけると嬉しいかも。

tailwindcssはUIコンポーネントを提供しないユーティリティクラスなので
最終的にはある程度自分でCSSを記述する必要があると思っていて、その際に
tailwindcssから提供されているクラス名であることを明示したい。
(宣言の順番とか、オリジナルのクラスの命名規則とかも決まってれば嬉しいかも。)

tailwindcss Configuration
tailwindcss Thema`

3.に関して感じたこと

これはシンプルにありがたい。使います。
と思いましたが、調べたらflexやらブレイクポイントやらのためのクラスが用意されている
だけなので、自分でCSSで書くのと正直かわらなくない?と思いましが。。。

ただ、前述したコンフィグの設定で細かい解像度の設定とかはできて、プリプロセッサが
それに応じたCSSを出力してくれるので、まぁ便利は便利かも?

まとめると、僕の欲しいものは
「面倒なことはやってくれるけど、基本的には自分でcss書きたい」なのかもしれない。

面倒なこととしては下記

  1. レスポンシブ対応とそのための解像度設定
  2. テーマの設定(アプリで統一したい色、線、フォント、基本的なマージン、パディング)

できるだけtailwindcssで通したい、という場合はカスタムスタイルという仕組みで
標準で提供されていないスタイルも定義可能。

  bg-[url('/img/hero-pattern.svg')]

※調べる過程で参考にさせていただいた、もしくは関連するからあとで読もうとなったリンク

tailwind cheatsheet
Storybookを導入してみてわかった、導入おすすめプロジェクトの特徴
Qiita React初心者がStorybookとAtomicDesignを使ったコンポーネント設計に挑戦していくお話【第2話 最初のコンポーネント】
zenn アトミックデザインの整理と再考
zenn Container/Presentationalパターン再入門
zenn Tailwind CSSを選定する際に考えたこと
MSW(Mock Service Worker)
zenn MSW で加速するフロントエンド開発

上部へスクロール