Gatsby.js+GraphQL環境にStorybookを導入してみる

思わぬ表示崩れを防いでくれるStorybook、みなさん活用していますか?
実データでは発生しづらいケースなどの表示確認をしやすく、自分は大変重宝しています。コードを書かないデザイナーやディレクターにも確認してもらいやすいのがいいですね
というわけで、今回はこのサイト(Gatsby.jsで作成)にStorybookを導入する流れをメモしつつ、今後導入しようとする方のお役に立てればということで記事にしていきたいと思います。

導入の基本編

Storybookの公式ページの指示通りに進めていきましょう。
すでに存在しているプロジェクトの中で、以下のコマンドを実行します。
インストールコマンド
npx sb init
このコマンドを実行するだけで、プロジェクトの使用技術を判断して最適な形でひな型を導入してくれるようです。
上記コマンドの処理が完了したら、すでにStorybookを起動できる状態になっています。
Storybookを起動するコマンドを実行してみましょう。
起動コマンド
yarn run storybook
すると以下のような画面が立ち上がります。
おめでとうございます、簡単でしたがこれでStorybookが使えるようになりました!
Storybookの初期画面

実際のコンポーネントを表示する

とはいえ、まだサンプルが表示されているだけなので、自分のサイトで使っているコンポーネントを表示していきましょう
適当な場所に MyComponent.stories.tsx のようなファイルを作り、中身を作っていきます。
(いろいろな書き方が可能ですが、シンプルな書き方で記述しています)
以下のコンポーネント名とpropsの値を変えるだけで表示されると思います。

Storyのひな型
import React from 'react';
import { Meta } from '@storybook/react/types-6-0';
import { MyComponent } from '../components/MyComponent';

export default {
  title: 'Components/MyComponent',
  component: MyComponent,
} as Meta;

export const PatternA = (): JSX.Element => (
  <MyComponent color="red" width={200} />
);
export const PatternB = (): JSX.Element => (
  <MyComponent color="blue" width={400} />
);


ここで「表示はされたけど、意図した表示とちょっと違うような?」と思った方がいるかもしれません。
その原因はおそらく以下のどちらかです。
  • リセットやベースとなるCSSが読み込まれていない
  • Storybookをインストールした時のサンプルCSSが効いている


リセットやベースとなるCSSが読み込まれていない

必要に応じて、preview.jsの中でimportをすることで、各Storyでもそのスタイルが効きます。
preview.jsの記述例
import 'ress';
import '../src/styles/base.css';


Storybookをインストールした時のサンプルCSSが効いている

これは検索しても情報が見つけづらく、詰まると意外と解決しづらい問題かもしれません。
Storybookをインストールするとサンプルとして、いくつかのコンポーネントとStoryを用意してくれますが、その中の page.css で要素セレクタを使ってバシバシスタイル指定をしています。
その指定が効いて予期せぬ表示になっている可能性があるので、中身をひととおり確認したら消してしまう方が良いかと思います。

GraphQLで引いてきたデータを表示する

ここはいろいろなやり方がありそうな気がするのですが、Storybookの表示には実データを引いてくるのではなく、それっぽいモックデータで事足りるので、かなり簡易な方法を選択しました。
GraphQLのお試し環境で、本番でデータを引いてくるのと同じクエリを実行し、その結果として返ってきたデータをそのまま使います。
GraphQLで取得したデータをStorybookで使うイメージ

取得した内容をコピペし、Storybookでこのように渡します。
jsxデータを直接記述する形式
const data = [
  {
    category: 'JavaScript',
    categorySlug: 'javascript',
  }, 
 {
    category: 'CSS',
    categorySlug: 'css',
  },
  {
    category: 'HTML',
    categorySlug: 'html',
  },
];

export const Default = (): JSX.Element => (
  <CategoryList data={data} />
);


実にシンプルで、作業時間もかなり短く済みます。
データ構造に変化があった時にはその都度対応が必要だったり、あんまり賢くない感じがしたり、ということに目をつむれば、コスパのいい方法です。

その他のつまりやすいところ

どうやらgatsbyのLinkとstorybookの相性が悪いらしく、普通のLinkを使っているコンポーネントを表示させようとするとエラーになってしまいます。
解決は難しくなく、以下のように置き換えるだけです(gatsby-linkのインストールをしたあとで)
Linkの置き換え
import { Link } from 'gatsby';
  ↓↓↓
import Link from 'gatsby-link';
この違いの詳細については調べきれていないのですが、表示や挙動をざっと確認した範囲では問題なさそうでした。

まとめ

若干雑な導入だった気もしますが、あくまで表示確認用のものなので、そこまで神経質にならずにザッと導入してみました。
Gatsby.jsやGraphQLを使っているための特別対応は多くなく、Storybookはどんな環境でも使えるいいツールだなということが再確認できた気がします。

この記事をシェアしてくれると小躍りします