環境構築 ∋ React

プロジェクトにpackage.jsonが置かれてる所から始めます。無い場合はyarn init -yで作りましょう。

JavaScript で始める場合必須モジュールは以下の5つです。

  1. @storybook/react
  2. react
  3. reacnt-dom
  4. @babel/core
  5. babel-loader

以下でインストールします。

yarn add -DE @storybook/react @babel/core babel-loader && \
yarn add -E react react-dom

次に設定ファイルで「どのファイルを Story 対象にするか」を指定します。設定ファイルはデフォルトで.storybook/main.jsになります。src/以下にある全ての.stories.js(この設定は.stories.tsも行ける)を対象にする場合以下のように設定します。

module.exports = {
  stories: ['../src/**/*.stories.[tj]s']
};

最初..で1つ戻っているのは設定ファイルから見てだからです。では早速その.stories.jsファイルを作成しましょう。
ここではbutton.stories.jsを以下のようになるように作りました。

.
├── .storybook
│   └── main.js
└── src
    └── components
        └── button
            └── button.stories.js
            

button.stories.jsの中身は、

import React from 'react';
import {Button} from '@storybook/react/demo';

export default {title: 'Button'};

export const withText = () => <Button>Hello Button</Button>;

export const withEmoji = () => (
  <Button>
    <span role="img" aria-label="so cool">
      😀 😎 👍 💯a
    </span>
  </Button>
);

にします。

defaultではこのファイルで作った各 Story を Button というグループ名でエクスポートしてます。それ以外にエクスポートしているものが Story でただの JSX で書いてます。

準備は整ったのであとはサーバーを建てて見てみましょう。binを直接でもいいですがここではrun-scriptを追加して、そのコマンドから建てることにします。

以下のコマンドを叩くとyarn storybookでサーバーを建てれます。npeは CLI で簡単にpackage.jsonを編集したり取得できる優れた CLI ツールです。

npx npe scripts.storybook start-storybook

では以下を叩くと、

yarn storybook

ランダムなポートでサーバーが立ち上がります。

╭─────────────────────────────────────────────────────╮
│                                                     │
│   Storybook 5.3.3 started                           │
│   18 s for manager and 17 s for preview             │
│                                                     │
│    Local:            http://localhost:52871/        │
│    On your network:  http://192.168.1.153:52871/    │
│                                                     │
╰─────────────────────────────────────────────────────╯

この場合だとhttp://localhost:52871/が見れる URL です。アクセスしてみてButtonの各 Story が見れるか確認しましょう。

上記の内容と同じことをしたリポジトリを置いておきます。

TypeScript 対応

stories ファイルに .tsx を含める

.storybook/main.jsstories['../src/**/*.stories.tsx']のように変更し、 TypeScript なストーリーファイルを Storybook が見るようにします。

Webpack 編集

Storybook の Webpack はデフォルトでは TypeScript をサポートしていません。storiesを変えただけではうまくそれらを扱えません。 それらを扱えるようにts-loaderを導入します。また、まだ TypeScript がインストールされてないならそれも入れます。

yarn add -D ts-loader typescript

そして.storybook/main.jsを再度編集します。storiesと同じ階層にはwebpackFinalというセクションが置け、ここで Webpack を弄れます。
このセクションは関数で、引数として Storybook が構築した Webpack Config を渡してくるので、そこに対して TypeScript 関連の設定を追加します。設定後は関数の戻り値としてその Config を返さなければなりません。

TypeScript 関連の設定は以下のように行います。

module.exports = {
  stories: /* ...略... */,
  webpackFinal(config) {
    config.module.rules.push({
      test: /\.tsx?$/,
      use: [
        {
          loader: require.resolve('ts-loader'),
          options: {
            transpileOnly: true
          }
        }
      ]
    })

    config.resolve.extensions.push('.ts', '.tsx');

    return config;
  }
};

ここで行ってることは2つです。

  1. .tsまたは.tsxファイルをts-loaderを通してトランスパイルする
  2. .tsまたは.tsxファイルは拡張子を省略してインポートできる

React 時の設定

もし React と一緒に使いたい場合は、以下のようになる TypeScript の設定が必要です。

  1. JSX を使い
  2. 要素の生成関数にはReact.createElementを使う

これにはcompilerOptions.jsxの値にreactを設定します。
また作ってるものがライブラリの場合はcompilerOptions.esModuleInteropfalseにしておくとトランスパイル後のコードが減ります。このオプションのオン・オフの違いはimport Reactimport * as Reactで読み込むか位の違いです。

React 時のプロジェクトについて置いておきます。

エラー

TypeScript 型関連

TS2305: Module '"../../@storybook/react/dist/client"' has no exported member 'RenderFunction'.

全文。

../../node_modules/@types/storybook__addon-knobs/index.d.ts:13:10 - error TS2305: Module '"../../@storybook/react/dist/clien
t"' has no exported member 'RenderFunction'.

13 import { RenderFunction } from '@storybook/react';
            ~~~~~~~~~~~~~~


Found 1 error.

このエラーはtscでビルドする時に(2020年2月7日頃)遭遇しました。

@5.0.x系の@types/storybook__addon-actions@types/storybook__addon-info@types/storybook__addon-knobsを使っていると起きる事があるようです。

起きた環境は@5.0.xを使っているyarnworkspacesnode_modulesをまとめているようなプロジェクトでした。

対処するには、それらを@^5.2.0以上にアップグレードするか、Yarn 機能でpackage.jsonresolutionsに、

{
  "resolutions": {
    "@types/storybook__addon-knobs": "^5.2.0"
  }
}

のように書いて再度yarnでインストールしてからビルドしたら通りました。