目次
概要
今回のブログポストではTypeScript
をベースにしたNext.js
プロジェクトにStorybook
を入れてコンポーネント主導開発(Component Driven Development)をやってみましょう。
ここで紹介するソースコードは下記のリンクで確認できます。
ブログリスト
このブログポストはシリーズで作成されています。次はNext.js
のシリーズリストです。
- [Next.js] 始まる
- [Next.js] TypeScript
- [Next.js] Prettier
- [Next.js] 絶対パスでコンポーネント追加
- [Next.js] テスト
- [Next.js] Storybook
- [Next.js] Storybookのバックグラウンド変更
- [Next.js] 多言語
- [Next.js] MUI
TypeScriptベースのNext.jsプロジェクトの生成
TypeScript
が適用されたNext.js
でStorybook
を使うため、下記のコマンドを使ってTypeScript
が適用されたNext.js
プロジェクトを生成します。
npx create-next-app --typescript start-storybook
Storybookのインストール
TypeScript
が適用されたNext.js
プロジェクトでStorybook
を使ってコンポーネント主導開発をするためにはStorybook
をインストールする必要があります。次のコマンドを実行してStorybook
をインストールします。
# cd start-storybook
npm install --save-dev sb
Storybookの初期化
Storybook
を使うためにはStorybook
を初期化して必要なライブラリをインストールする必要があります。次のコマンドを実行してStorybook
を初期化します。
npx sb init --builder webpack5
その後、次のように自動でStorybook
が初期化されることが確認できます。
sb init - the simplest way to add a Storybook to your project.
• Detecting project type. ✓
There seems to be a Storybook already available in this project.
Apply following command to force:
sb init [options] -f
🔎 checking 'cra5'
🔎 checking 'webpack5'
🔎 checking 'angular12'
🔎 checking 'mainjsFramework'
Unable to find storybook main.js config, skipping
🔎 checking 'eslintPlugin'
最後に、次のような質問が出ます。
? Do you want to run the 'eslintPlugin' fix on your project? › (y/N)
ESLint
を使ってコードを検査している場合はy
キーを押して、違う場合はN
キーを押して進めます。このブログポストではy
キーを押して進めました。
その後、次のようにStorybook
に必要なライブラリが自動でインストールされることが確認できるし、Storybook
を実行するスクリプトが自動で作成されることが確認できます。
{
...
"scripts": {
...
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
...
"devDependencies": {
"@babel/core": "^7.17.7",
"@storybook/addon-actions": "^6.4.19",
"@storybook/addon-essentials": "^6.4.19",
"@storybook/addon-interactions": "^6.4.19",
"@storybook/addon-links": "^6.4.19",
"@storybook/react": "^6.4.19",
"@storybook/testing-library": "^0.0.9",
"babel-loader": "^8.2.3",
"eslint-plugin-storybook": "^0.5.7",
...
}
}
また、次のようにStorybook
を使う方法を教えるため、サンプルコードが一緒に生成されることが確認できます。
./.storybook/...
:Storybook
に関する設定ファイル./stories/...
:Storybook
のサンプルファイル
publicフォルダ設定
Next.js
のpublic
フォルダにあるstatic
ファイル(イメージ)をStorybook
でも認識できるようにするためscripts
を次のように修正します。
{
...
"scripts": {
...
"storybook": "start-storybook -p 6006 -s ./public",
"build-storybook": "build-storybook -s public"
},
...
}
Storybookの実行
今まで設定したStorybook
を実行して、Storybook
が上手くインストールされたか確認してみましょう。次のコマンドを実行してStorybook
を実行します。
npm run storybook
そしたら、ブラウザにhttp://localhost:6006/
が事項で開いて、次のような画面が表示されることが確認できます。
この画面は./stories/Introduction.stories.mdx
ファイル内容が表示された画面です。
Storybookの確認
実行されたStorybook
の左メニューのButton > Primary
を押すと次のような画面が表示されます。
この画面は./stories/Button.stories.tsx
ファイルの内容が表示された画面です。
サンプルコード確認
もっと詳しくサンプルコードを確認してみましょう。Button
コンポーネント(./stories/Button.tsx
)は次のようになります。
import React from 'react';
import './button.css';
interface ButtonProps {
primary?: boolean;
backgroundColor?: string;
size?: 'small' | 'medium' | 'large';
label: string;
onClick?: () => void;
}
export const Button = ({
primary = false,
size = 'medium',
backgroundColor,
label,
...props
}: ButtonProps) => {
...
};
Button
コンポーネントはprimary
, backgroundColor
など色んなProps
を持っていることが確認できます。次はStorybook
ファイル(./stories/Button.stories.tsx
)の内容を確認してみましょう。
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { Button } from './Button';
export default {
title: 'Example/Button',
component: Button,
argTypes: {
backgroundColor: { control: 'color' },
},
} as ComponentMeta<typeof Button>;
const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
primary: true,
label: 'Button',
};
export const Secondary = Template.bind({});
Secondary.args = {
label: 'Button',
};
export const Large = Template.bind({});
Large.args = {
size: 'large',
label: 'Button',
};
export const Small = Template.bind({});
Small.args = {
size: 'small',
label: 'Button',
};
まず、Storybook
に表示されるコンポーネントを用意します。
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { Button } from './Button';
export default {
title: 'Example/Button',
component: Button,
argTypes: {
backgroundColor: { control: 'color' },
},
} as ComponentMeta<typeof Button>;
const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />;
...
argTypes
のbackgroundColor
にcontrol: 'color'
を設定すると、次のようにStorybook
で色を選択することができます。
その後、画面に表示されるStory
を作成します。
...
export const Primary = Template.bind({});
Primary.args = {
primary: true,
label: 'Button',
};
...
ここではargs
にButton
コンポーネントのProps
を設定して色んなStory
を作ることができます。
Storybookの設定
まずNext.js
のglobals.css
をStorybook
でも使えるように設定する必要があります。./storybook/preview.js
ファイルを開いて下記のように修正します。
import '../styles/globals.css'
export const parameters = {
...
}
現在はStorybook
を作成するためには./stories
フォルダに作成する必要があります。しかし、普通コンポーネントは./components
フォルダを生成して管理をします。
このようにStorybook
を他のフォルダで作成するためには./.storybook/main.js
ファイルを修正する必要があります。./.storybook/main.js
ファイルを開いて下記のように修正します。
module.exports = {
"stories": [
"../**/*.stories.mdx",
"../**/*.stories.@(js|jsx|ts|tsx)"
],
...
}
今後はどんなフォルダでも.stories.tsx
ファイル名を持ってれば、Storybook
がこれを認識して画面に表示させます。これを確認するためん./components/SampleButton
フォルダを生成して次のようにファイルをコピーしてみます。
./stories/button.css
>./components/SampleButton/index.css
./stories/Button.stories.tsx
>./components/SampleButton/index.stories.tsx
./stories/Button.tsx
>./components/SampleButton/index.tsx
そして、./components/SampleButton/index.tsx
ファイルを開いて下記のように修正します。
...
import './index.css';
...
export const SampleButton = ({
...
}: ButtonProps) => {
...
};
その後、./components/SampleButton/index.stories.tsx
ファイルを開いて下記のように修正します。
...
import { SampleButton } from '.';
...
export default {
title: 'Example/SampleButton',
component: SampleButton,
...,
} as ComponentMeta<typeof SampleButton>;
const Template: ComponentStory<typeof SampleButton> = (args) => (
<SampleButton {...args} />
);
...
Storybook
の設定を変更したので、これを反映されるため、現在実行中のStorybook
を終了して、再び実行します。Storybook
が再び実行されると次のように私たちが作ったSampleButton
が上手く表示されることが確認できます。
完了
今回のブログポストではTypeScript
をベースにするNext.js
プロジェクトにコンポーネント主導開発をするため、Storybook
を設定する方法についてみてみました。今度からアプリを開発するとき、Storybook
を見ながら、コンポーネントに集中して開発してみてください。
私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!
アプリ広報
Deku
が開発したアプリを使ってみてください。Deku
が開発したアプリはFlutterで開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。