なにかとおしごとの場面をはじめ、最近 Storybook に触れる機会が多々存在しており、先日リリースされた v7 について書かせていただきました。
Storybook v7
先日 Storybook v7 が リリース されました。
Today's the day: #StorybookDay is here! 🎉
— Storybook (@storybookjs) March 14, 2023
From 10 am PDT, join a line-up of world class front-end devs, community experts and Storybook maintainers. Learn about cutting-edge UI development & explore everything new with Storybook 7.0.
📅 Get involved ↓https://t.co/OWgWGQ2VR3
これまで Webpack を基調としてビルドしてきた Storybook が、この度 Vite に変更されている点は大変、大きなポイントのひとつとなっています。
手元の Storybook 環境を v7 に更新する場合は、まず npx storybook@latest upgrade
を実行してください。
# storybook@latest
npx storybook@latest upgrade
yarn をお使いの方は、適宜読み替えてください。
基本的にこれだけで完了させられます。
続いて Storybook v7 の主な特長を下に示します。
- 使用コマンドの変更
- Vite 基調のビルドへ更新
- CSF (CSF3) における型定義改善
- その他
- MDX の v2 サポート
- Jest と Testing Library を利用したインタラクションテストのサポート
- Playwright を利用した Web ブラウザテストのサポート
使用コマンドの変更
Local における serve コマンドが start-storybook
から storybook dev
へ、また静的な HTML へ吐き出すコマンドが build-storybook
から storybook build
へ変更されています。
/* 変更前 */
{
"scripts": {
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
}
}
/* 変更後 */
{
"scripts": {
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
}
}
Vite 基調のビルドへ更新
先に言ったように Vite を基調としてビルドされている点が、大きなポイントのひとつとなっています。
それはすなわち、これまで Storybook 上で Vite を利用してビルドするのに必要だった @storybook/builder-vite を .storybook/main.js の中で明示しなくても良くなっています。
/* 変更前 */
module.exports = {
framework: '@storybook/vue3',
core: {
builder: '@storybook/builder-vite',
},
}
/* 変更後 */
module.exports = {
framework: '@storybook/vue3-vite',
}
CSF (CSF3) における型定義改善
まず、ここで CSF とは Component Story Format の略称となり、一般的に XXX.stories.ts
のようなファイル形式を指しています。
Storybook 上で描画される予定の最小単位 (story) と、そのメタデータ (meta) から構成されており、この CSF では、story 及びそのメタデータを ESM を用いて定義することとなります。
default export のモジュールで共通の story 及びそのメタデータを定義するのに対し、named export のモジュールでは対象コンポーネントの story 及びそのメタデータを定義します。
実際 story の型定義で、個別のコンポーネントにおける props 型定義が反映される (generics が使用される) ようなっています。
export interface ButtonProps {}
/* 変更前 */
import { Story } from '@storybook/react'
const Template: Story = (args, { argTypes }) => ({
//
})
export interface ButtonProps {}
/* 変更後 */
import { StoryObj } from '@storybook/react'
const Template: StoryObj<typeof ButtonProps> = (args, { argTypes }) => ({
//
})
import { StoryFn } from '@storybook/react'
const Template: StoryFn<ButtonProps> = (args, { argTypes }) => ({
//
})
なお、Vue でも React 同様に story の型定義が変更されている点には、ひとつ注意しておきたい。
export interface ButtonProps {}
/* 変更前 */
import { Story } from '@storybook/vue3'
const Template: Story = (args, { argTypes }) => ({
//
})
export interface ButtonProps {}
/* 変更後 */
import { StoryObj } from '@storybook/vue3'
const Template: StoryObj<typeof ButtonProps> = (args, { argTypes }) => ({
//
})
import { StoryFn } from '@storybook/vue3'
const Template: StoryFn<ButtonProps> = (args, { argTypes }) => ({
//
})