feature image

2022年12月5日 | ブログ記事

Storybook使ってみた

この記事はアドベントカレンダー2022の11日目の記事です。

こんにちは。mehm8128です。
traPではSysAd班に所属してJomonとtraPortfolioの開発に関わっています。
3Q最後の期末試験の2時間前に書いています。

今回はtraPに関する開発の話ではないですが、個人開発でStorybookを使ってみた話を書いていきます。
前にちょっと使ってみてよく分からんってなって1回諦めたのですが、最近参加させてもらっているインターン先で使ってなんとなく理解したので個人開発でも使ってみました。

Storybookとは

https://storybook.js.org/
これです。

Storybook is a frontend workshop for building UI components and pages in isolation.

UIコンポーネントやページを他から独立した状態で管理して開発を進めていくことができるツールです。
まだ使い始めたばかりで便利さを完全に理解しているわけではないですが、導入に当たって色々と苦労したのでメモ程度に書き残していきたいと思います。
環境はNext.js&TypeScriptです。Vue.jsとかでも使えるらしいです。

ちなみにtraPでは以下のtraP Collectionのプロジェクトで使われているらしいです。SysAd班集会の進捗報告でStorybookが良いって話を聞いて、初めてStorybookの存在を知りました。
https://github.com/traPtitech/trap-collection-launcher
https://github.com/traPtitech/trap-collection-admin

使い方

npx storybook init
npm run storybook
これだけで起動できます。
そうするとstoriesというディレクトリができていると思うのですが、そこにはexamplesが入っています。Button.tsxがコンポーネントで、Button.stories.tsxがそのコンポーネントに対するstorybookの設定ファイルです。このファイルに色々と書き込むことでnpm run storybookしたときに起動するGUIでコンポーネントを見ることができたり、コンポーネントの状態を変えたりすることができるようになります。

試しにButton.stories.tsxを見てみます。

export default {
  title: 'Example/Button',
  component: Button,
  argTypes: {
    backgroundColor: { control: 'color' }
  }
} as ComponentMeta<typeof Button>

titleではGUIで表示される名前を設定できます。スラッシュでディレクトリ構造にできます。
componentは使うコンポーネントを指定します。
argTypesではコンポーネントのpropsに渡す値を指定できます。
controlを使うとGUI上で値を設定できます。今回はcolorなのでカラーパレットを使えますが、selectにして値の配列を指定すると選択肢の中から選択できるような表示にすることもできます。

const Template: ComponentStory<typeof Button> = args => <Button {...args} />

export const Primary = Template.bind({})
Primary.args = {
  primary: true,
  label: 'Button'
}

実際にGUIで表示するコンポーネントの設定です。この一つ一つをStoryと呼ぶらしいです。
Templateで基本となる設定をして、後ろのPrimarySecondaryなどで、propsを設定していくつかの種類のボタンを作っています。

諸々の設定

既存のプロジェクトにStorybookを導入するにあたって、導入した設定たちは以下の通りです。

これらを今から説明していきます。
(ここから先は期末試験後に書いています)

importで絶対パスを使えるように

Module not found: Error: Can't resolve なんたら in なんたらみたいなエラーが大量に出てたのでなんだこれって調べたらこの記事にたどり着きました。
https://zenn.dev/enish/articles/cde07d3d22f95b
記事の通りに.storybook/main.jsをいじったら直りました。

Windi CSSを使えるように

スタイルが当たっていなくてWindi CSSが適用できていなさそうだったので調べたら公式のこのページにたどり着きました。
https://windicss.org/integrations/webpack.html#storybook
この通りにしたら直りました。

Ant Designを使えるように

Ant DesignというのはUIライブラリなのですが、これもWindi CSS同様、スタイルが当たってなさそうだったので調べてみたところ、どの記事が参考になったか覚えてないのですが、.storybook/preview.jsでスタイルをimportすればよさそうということが判明しました。
ただし、Ant Designの場合はglobal.css@import "antd/dist/antd.css";として読み込んでいるので、Ant Designのスタイルもimportしてさらにglobal.cssに書いてあるスタイルもimportしようとすると表示がおかしくなってしまったので、importするのはglobal.cssだけ十分でした(styleディレクトリに他にCSSファイルがあるなら同様にしてimportするといいと思います)。

.storybook/previewはNext.jsでいう_app.tsxみたいなもので、Storybookでは各コンポーネントを独立して表示していて_app.tsxは読み込まれないので、代わりに.storybook/previewで全体に適用させたいスタイルなどを設定するんですね。

Recoilを使えるように

上記補足のように、_app.tsxが読み込まれないので<RecoilRoot></RecoilRoot>も適用されず、Recoilが使えていない状態です。
ここではStorybookのDecoratorという機能を使うとよさそうということが分かりました。
https://storybook.js.org/docs/react/writing-stories/decorators
僕は.storybook/preview.jsでこんな感じ↓でdecoratorを定義して、

export const decorators = [
	(Story) => (
		<StoryWrapper>
			<Story />
		</StoryWrapper>
	),
]

<StoryWrapper></StoryWrapper>

<RecoilRoot>
    {children}
</RecoilRoot>

みたいになっているコンポーネントにしています(実際には/GET meのリクエストを飛ばす処理を書いたり、Reactの比較的新しい機能であるSuspenseを入れたりしています)。

atomの初期値を設定したい場合は<RecoilRoot>initializeStateを渡せばよいのですが、.storybook/preview.jsでdecoratorの設定をしてる場合はストーリーごとに設定できなくなってしまうので、それが嫌なときはストーリーごと(もしくはコンポーネントごと)に<RecoilRoot>のdecoratorを設定することになりそうです。

next/routerを使えるように

これも設定する必要がありました。調べると色んなやり方が出てきてどれにするか悩んだのですが、これにしました。
https://storybook.js.org/addons/storybook-addon-next-router
書いてある通りにやればできました。

next/imageを使えるように

これも設定する必要がありました。
https://xenox.dev/next-image-with-storybookjs/

MSWを使えるように

MSWという、モックサーバーを使えるようになるライブラリがあります。
https://mswjs.io/
これをStorybookで使いたかったので調べました。
https://zenn.dev/rabbit/articles/dd9b04940b93fe
書いてある通りにすればできました。
MSWはJomonでも導入していて、かなり便利なのでおすすめです。

Chromaticを使う

StorybookにはChromaticという、公式推奨のテスト用ツールがあります。
ビジュアルレグレッションテストってやつですね。
ビジュアルレグレッションテストはサイバーエージェントさんのWeb Speed Hackathonでも使われていましたね。
https://storybook.js.org/docs/react/writing-tests/visual-testing
https://zenn.dev/keitakn/articles/storybook-deploy-to-chromatic
https://moneyforward.com/engineers_blog/2022/04/04/improved-design-reviews/
小規模な個人開発で使うメリットは少なそうですが、面白そう&便利そうということでやってみました。
Github Actionsでpush時に自動でテストを回してくれるようにも設定できます。
https://www.chromatic.com/docs/github-actions
が、環境変数が上手く読み込めてなくてaxiosのエラーが出てしまうので、いつか直したいと思っています。

最後に

色々導入してるプロジェクトだと色々設定が必要でちょっと大変でしたが、使いこなせればとても便利だと思うので積極的に使っていきたいと思います。

明日の担当はs9くんです!お楽しみに~

mehm8128 icon
この記事を書いた人
mehm8128

21B工学院。アルゴリズム班とSysAd班とCTF班に入ってます。

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2022年9月26日
競プロしかシラン人間が web アプリ QK Judge を作った話
tqk icon tqk
2022年11月27日
Chromebook&VSCode Server(プレビューアクセスなし)で開発環境を作る
oribe icon oribe
2022年3月27日
ReactでToDoリストを作る(後編)
mehm8128 icon mehm8128
2022年3月19日
ReactでToDoリストを作る(中編)
mehm8128 icon mehm8128
2022年3月18日
ReactでToDoリストを作る(前編)
mehm8128 icon mehm8128
2022年12月19日
2020春ハッカソン参加記 4班『外郎集め』【AdC 2022 25日目】
kashiwade icon kashiwade
記事一覧 タグ一覧 Google アナリティクスについて