環境構築
TypeScript
github-pages
React
storybook

Storybook V5+React+TypeScriptで環境構築

alt

StorybookのV5.0がリリースされました。

Storybook+React+TypeScriptで試してみたので、内容をまとめてみました。

インストールからサンプルのコンポーネント作成と、GitHub Pagesへのデプロイまで記載しています。

まだドキュメントが古いものも多く、試行錯誤しながらでしたが、V4までと比べてTypeScript周りの設定が楽になった気がします。

なお、手順はNode.jscreate-react-appはインストール済みの前提です。

ソース

デモ


2019/03/09追記


  • @storybook/addon-consoleを追加


  • *.stories.jsもストーリの対象に追加


  • src/stories/*jsjsxはストーリ対象とするように修正

  • withInfoをaddDecoratorで指定するように変更


土台の作成

まず、create-react-appでプロジェクトを作成します。

create-react-app storybook-react-ts --typescript

作成したら、Storybookを登録して初期化処理を実行します。

cd storybook-react-ts

yarn add -D @storybook/cli
yarn sb init

実行すると、Storybookの設定が入ったフォルダとストーリーのサンプルが追加されています。

.storybook/

addons.js
config.js
src/stories/
index.js

また、package.jsonにStorybookの起動とビルドのコマンドが追加されます。


package.json

  "scripts": {

~
"storybook": "start-storybook -p 9009 -s public",
"build-storybook": "build-storybook -s public"
}

yarn storybookとコマンドを入れると、Storybookの画面が開きます。

storybook-react-ts-01.png

とりあえずこれで使えるようになりしたが、アドオンを追加したりストーリーをTypeScriptで作成できるようにしていきます。


カスタマイズ

使いやすくするため、以下の作業を行っていきます。


  • アドオン登録


    • addon-knobs
      プロパティを変更できる画面を追加

    • addon-viewport
      ビューポートを切り替えるボタンを追加

    • addon-storysource
      ストーリーのソースを表示

    • addon-info
      ストーリーの例とか説明を追加

    • react-docgen-typescript-loader
      TypeScriptの型からコンポーネントのプロパティ説明を追加

    • addon-console
      Actionsタブにコンソールログを表示する



  • ストーリーをTypeScriptで作成できるように


  • *.stories.tsxのファイル名でストーリーを作成できるように


アドオン追加

yarn add -D @storybook/addon-knobs \

@storybook/addon-viewport \
@storybook/addon-storysource \
react-docgen-typescript-loader \
@storybook/addon-info \
@storybook/addon-console


型定義追加

yarn add -D @types/storybook__react \

@types/storybook__addon-info \
@types/storybook__addon-actions \
@types/storybook__addon-knobs


Storybookの設定変更

パッケージの登録が終わったら、Storybookの設定に定義を追加していきます。


.storybook/addons.js

import '@storybook/addon-actions/register';

import '@storybook/addon-links/register';
import '@storybook/addon-knobs/register';
import '@storybook/addon-viewport/register';
import '@storybook/addon-storysource/register';
import '@storybook/addon-console';

次に、.storybook/webpack.config.jsのファイルを作成し、

TypeScriptのソースをアドインに渡す処理を追加します。


.storybook/webpack.config.js

const path = require("path");

module.exports = ({ config }) => {
config.module.rules.push({
test: /\.(ts|tsx)$/,
use: [
{
loader: require.resolve("react-docgen-typescript-loader")
},
{
loader: require.resolve('@storybook/addon-storysource/loader'),
options: { parser: 'typescript' }
}
]
});
config.resolve.extensions.push(".ts", ".tsx");
return config;
};

次は、コンソールログをActionsタブに表示する処理と、TypeScriptで作成したストーリーを読み込む処理を追加します。


.storybook/config.js

import { configure } from '@storybook/react';

setConsoleOptions({
panelExclude: []
});

function loadStories() {
let req = require.context("../src/stories", true, /.(tsx|js)$/);
req.keys().forEach(filename => req(filename));

req = require.context("../src", true, /.stories.(tsx|js)$/);
req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);



コンポーネント作成

サンプルのコンポーネントを作成します。


src/component/Example/index.tsx

import React, { useState, useCallback } from "react";

export interface ExampleProps {
/** 表示するテキスト */
text: string;
/**
* true: テキスト表示 false: テキスト非表示
* @default false
*/

flag?: boolean;
/** ボタンを押した時のイベントハンドラ */
action(): void;
}

const Example = (props: ExampleProps) => {
const { text, flag, action } = props;
const [count, countChg] = useState(0);
const countUp = useCallback(() => countChg(prev => prev + 1), []);
const countDown = useCallback(() => countChg(prev => prev - 1), []);

return (
<div>
{flag && <p>{text}</p>}
<button onClick={action}>ボタン</button>
<p>count:{count}</p>
<button onClick={countUp}>+</button>
<button onClick={countDown}>-</button>
</div>
);
};

export default Example;


addon-knobs等のデモ用に、適当なプロパティを作っています。

また、Reactの最新版に対応しているかを確認するためReact Hooksを使ってます。

プロパティの定義にはコメントを入れておけばストーリに表示されるので、適当に入れておきます。


ストーリー(TypeScript)追加

作成したコンポーネントに対応するストーリーを、登録したアドオンも使用して作成します。

:src/components/Example/index.stories.tsx

import React from "react";

import { storiesOf } from "@storybook/react";
import { withInfo } from "@storybook/addon-info";
import { withKnobs, text, boolean } from "@storybook/addon-knobs";
import { action } from "@storybook/addon-actions";

import Example from "../Example";

const components = storiesOf("Components", module);
components
.addDecorator(withKnobs)
.addDecorator(withInfo({ inline: true }))
.add("Example", () => (
<Example
text={text("テキスト", "ああああ")}
flag={boolean("テキスト表示", true)}
action={action("ぽちっとな")}
/>
));

yarn storybookとコマンドを入れると、Storybookの画面が開きます。

storybook-react-ts-02.png


GitHub Pagesに登録

デプロイ用のツールを登録します。

yarn add -D gh-pages

登録したら、起動コマンドを追加します。


package.json

  "scripts": {

~
"predeploy": "build-storybook",
"deploy": "gh-pages -d storybook-static"
}

predeployはデプロイ前の自動ビルドの設定、deployではbuild-storybookで出力されるフォルダstorybook-staticを指定します。

デプロイ実行はyarn deployです。

完了すると以下のアドレスにデプロイされます。

https://XXXXX.github.io/storybook-react-ts

デプロイ時に作成されたファイルは不要だと思うので、.gitignoreに登録しておきます。


.gitignore

/storybook-static