6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1人フロントエンドAdvent Calendar 2023

Day 25

一足先にStorybook8の世界を覗いてみる

Posted at

はじめに

現在Storybookのバージョン8がalpha版としてリリースされています。
まだ、安定して利用できるバージョンではないですが、バージョン7のコードを書く上であらかじめ気をつけておきたい点を把握したり、より快適で楽しい新機能を体験するために、足を踏み入れてみます。

この記事では、バージョン8へのアップデート方法と、バージョン8での変更を確認していきます。

この記事はStorybookのバージョン8.0.0-alpha4時点での内容になります。今後のバージョンアップで内容が変更されることは大いに考えられるので注意してください。

バージョンアップ

Storybookバージョン8には以下のようなコマンドであげます。

npx storybook@next upgrade --prerelease

バージョン7の時と違って、コードベースの大きな変更は必要ありませんでした。

変更

Storybook8までの変更履歴マイグレーションガイドを参考に記述します。

利用環境

Nodejsの最低バージョンが18になりました。利用する際はNodejsバージョン18以降のものを使うようにしてください。
Nextjsの13.5未満のバージョンへのサポートがされなくなりました。
Angularの15未満のバージョンがサポートされなくなりました。

actionのモック

Storybookではデフォルトで以下のような初期設定が行われます。

preview.ts
const preview: Preview = {
  parameters: { 
    actions: { argTypesRegex: "^on[A-Z].*" },
  },
};

export default preview;

Storybookは、ここで設定しているactionsargTypesRegexに一致する関数がpropsとして渡されるコンポーネントを扱う場合、その関数を自動でspyするようになります。
これによって以下のように、簡単にテストを記述できるのでとても便利でした。

import type { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, within } from '@storybook/test';

import { Button } from './Button';

export const Primary: Story = {
  args: {
    primary: true,
    label: 'Button',
  },
  play: async ({ args, canvasElement }) => {
    await userEvent.click(within(canvasElement).getByRole('button'));
    // onClickに何の設定もせずに`toHaveBeenCalled`を確認できる!
    await expect(args.onClick).toHaveBeenCalled();
  },
};

しかし、この機能にはいくつか問題がありました。それは、コンポーネントを解析するライブラリ(decgen)がない時に動作しないことでした。
これがない環境でレンダリングできるようにすることでテストの幅が広がりますし、解析が必要な他の場面があっても遅延読み込みが可能になり、パフォーマンスが向上します。
そのため、今後はこのような暗黙的に対象をspyするのはやめて@storybook/testを用いて明示的にspyさせる用になります。

import type { Meta, StoryObj } from '@storybook/react';
import { expect, fn, userEvent, within } from '@storybook/test';

import { Button } from './Button';

export const Primary: Story = {
  args: {
    primary: true,
    label: 'Button',
    onButton: fn(),
  },
  play: async ({ args, canvasElement }) => {
    await userEvent.click(within(canvasElement).getByRole('button'));
    // onClickに何の設定もせずに`toHaveBeenCalled`を確認できる!
    await expect(args.onClick).toHaveBeenCalled();
  },
};

(今のバージョンだとまだ自動でspyされてしまいました。)

タイトルの自動設定

Storybook7からStoryを生成するパスを自動生成できるようになりました。
以下の例だとButtonのStoryはEXAMPLE/Buttonというパスに生成されています。
スクリーンショット 2023-12-24 12.58.37.png
これは、example/Button.stories.tsxのStoryを自動生成した時に生成される場所です。
このようなパスの自動生成にはexample/Form.Button.stories.tsxのようなStoryを生成した時にEXAMPLE/Formというパスに生成されるというようなバグがありました。
今後は.stories前のEXAMPLE/Form.Buttonに生成されます。

react-docgen

Storybookではreact-docgen-typescriptを用いてコンポーネントのpropsなどのメタ情報を解析しています。
バージョン8.0はそのデフォルトの機能をreact-docgenにしました。これによって解析効率があがり、起動時間の大幅な短縮を図っています。
この変更によって基本的なTypeScript構造しか変更できなくなったので、元の設定にしたい場合は設定を追加してください。

main.ts
typescript: {
  reactDocgen: 'react-docgen-typescript',
}

マネージャーUI

マネージャーUIは青色で囲んだ部分です。
スクリーンショット 2023-12-24 12.23.41 4.png
この部分はこれまで、Reactのバージョン16で作成されていましたが、このバージョンアップでReact18を用いて作成したものになりました。

addon.setConfig

StorybookのUIを設定するsetConfigの一部が変更されました。

Storyの一覧を表示しているナビゲーションを出すかどうかを決めるshowNavnavSizeになります。出すかどうかではなく、サイズを数値で指定するようにします。

アドオンの設定を表示するパネルを出すかどうかを決めるshowPanelbottomPanelHeightrightPanelWidthになります。同じく数値で指定するようになります。

fullScreenはこれらを組み合わせて表示できるので、サポートされなくなりました。

@storybook/components

@storybook/componentsはStorybookとそのアドオンで利用されるUIコンポーネントライブラリです。
このライブラリからはForm.Buttonのように複数のボタンコンポーネントが散らばっていました。
バージョン8では1つのButtonに纏まりました(IconButtonだけは別として残っています)。
さらに、ButtonIconButtonのpropsがいくつか変更されました。
isLinkが非推奨になってasChildを使うように、smallが非推奨になってsizeを使うように、その他いくつかのpropsが非推奨になってvariantでまとめて変更できるようになります。

@storybook/componentsからアイコンがいくつか提供されていましたが、今後はそれが非推奨となります。
別のライブラリの@storybook/iconsから提供されるものを使うことが推奨されます。

今後のバージョンアップ予定

2024年1月29日にbeta版のリリース、2024年2月13日にRelease Candidate版としてリリース、2024年2月27日にstable版としてリリースされる予定です。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?