Storybook は、アプリのコンポーネントを分離してフラットな階層でテストできるツールです。 ストーリーブックは、指定された入力と出力を備えたコンポーネントを優れたブラウザービューで表示する一連のストーリーです。

StorybookはReactプロジェクトで非常に人気があり、AngularおよびVueプロジェクトのサポートが v3.3.0 で追加されたため、Angularコンポーネントのストーリーを作成するために同じように簡単に使用できるようになりました。

基本的な使用法だけでなく、Angular用のStorybookの設定についても簡単に説明します。

設定

Storybookには、プロジェクトに簡単に追加できるCLIツールが付属しています。 まず、 @ storybook /cliパッケージをグローバルにインストールします。

# Yarn:
$ yarn global add @storybook/cli

# or npm:
$ npm i @storybook/cli -g

ここで、Angularプロジェクトのルートで、getstorybookコマンドを実行します。

$ getstorybook

このコマンドは、それがAngularプロジェクトであることを自動検出し、必要な構成、devDependencies、およびnpmスクリプトを追加します。

たとえば、この記事の執筆時点では、次のdevDependenciesがプロジェクトに追加されています。

"@storybook/angular": "^3.3.15",
"@storybook/addon-notes": "^3.3.15",
"@storybook/addon-actions": "^3.3.15",
"@storybook/addon-links": "^3.3.15",
"@storybook/addons": "^3.3.15",
"babel-core": "^6.26.0"

また、次のnpmスクリプトもプロジェクトのpackage.jsonファイルに追加されます。

"scripts": {
  ...
  "storybook": "start-storybook -p 6006",
  "build-storybook": "build-storybook"
},

これで、 storybooknpmスクリプトを呼び出して試すことができます。

$ npm run storybook

これにより、ポート 6006 でローカルWebpackサーバーが起動し、 http:// localhost:6006/にアクセスして生成されたストーリーブックにアクセスできます。 表示されるのは、プロジェクトのルートにあるstoriesフォルダーの下のindex.stories.tsファイルから生成されたストーリーブックの例です。 生成されたストーリーブックは次のようになります。

Initial Storybook example

ローカルサーバーにはwebpackのホットモジュール置換(HMR)が装備されているため、ストーリーへの変更は生成されたストーリーブックに自動的に反映されます。

構文とAPIの例については、/stories/index.stories.tsで生成されたサンプルストーリーをご覧ください。

あなたの最初の物語

次に、ストーリーブックの使用法の概要を説明するために、簡単なカードコンポーネントとそのコンポーネントのいくつかのストーリーを作成しましょう。 コンポーネントのテンプレートは次のとおりです。

card.component.html
<h1>{{ title }}</h1>
<h2>{{ subtitle }}</h2>

<hr *ngIf="title || subtitle">

<p>{{ content }}</p>

<button (click)="handleBtnClick()">Click me!</button>

そして、これが私たちのコンポーネントのクラスです:

card.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-card',
  templateUrl: './card.component.html',
  styles: [
    `
    :host {
      text-align: center;
      background: white;
      display: block;
      padding: .45rem .65rem;
      border-radius: 3px;
      max-width: 325px;
      box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
    }
h2 {
  color: #c85f7f;
}

p {
  text-align: center;
}  `
  ]
})
export class CardComponent {
  @Input('title') title;
  @Input('subtitle') subtitle;
  @Input('content') content = '😄';
  @Output() btnClicked = new EventEmitter<boolean>();
  constructor() {}

ご覧のとおり、これはいくつかの入力と1つの出力を使用する非常に単純なコンポーネントです。 また、:host セレクターを使用して、コンポーネントのシェルのスタイルを設定しています。


次に、 index.stories.ts を変更して、カードコンポーネントにいくつかのストーリーを追加しましょう。

index.stories.ts
import { storiesOf } from '@storybook/angular';
import { withNotes } from '@storybook/addon-notes';
import { action } from '@storybook/addon-actions';

import { CardComponent } from '../src/app/card/card.component';
storiesOf('Card', module)
  .add('empty', () => ({
    component: CardComponent,
    props: {}
  }))
  .add('with title', () => ({
    component: CardComponent,
    props: {
      title: 'Hello card!'
    }
  }))
  .add('with title and subtitle', () => ({
    component: CardComponent,
    props: {
      title: 'Hello card!',
      subtitle: 'Well hello there 👋'
    }
  }))
  .add(
    'with notes',
    withNotes('Just a few notes about this story...')(() => ({
      component: CardComponent,
      props: {}
    }))
  )
  .add('with action', () => ({
    component: CardComponent,
    props: {
      title: 'A card...',
      subtitle: 'Waiting to be clicked-on',
      btnClicked: action('👊 Button was clicked')
    }
  }));

注意すべき点がいくつかあります。

  • ご覧のとおり、ストーリーは、 storyOf()の呼び出しで add()の呼び出しを連鎖させることによって作成されます。
  • add()は、ストーリーの名前と、コンポーネントと小道具(入力と出力)を含むオブジェクトを返す関数を取ります。
  • 出力によってトリガーされたアクションは、actionアドオンを使用してログに記録できます。
  • withNotes アドオンを使用して、ストーリーにメモを追加できます。

Storybookで使用できる他のアドオンのリストについては、このページを参照してください。


この例では、Angularアプリのグローバルスタイルを生成されたストーリーブックに反映させたいと思いました。 Storybookによってプロジェクトのルートに追加された.configフォルダーにpreview-head.htmlというファイルを追加するのと同じくらい簡単です。 そのファイルには、ドキュメントの先頭に入るものなら何でも追加できます。 それでは、グローバルスタイルを追加しましょう。

プレビュー-head.html
<style>
  body {
    background: #f3f3f3;
    font-family: Roboto, sans-serif;
    color: #6ba083;
  }
</style>

…そして、ストーリーブックは次のようになります。

Storybook with card stories

展開用のストーリーブックの作成

Githubページなどの静的ホスティングサービスにデプロイできる静的ファイルを使用してストーリーブックを簡単に生成できます。 これにより、チームの他のメンバーが簡単に参照できるストーリーブックをホストできます。

build-storybooknpmスクリプトを呼び出すだけです。

$ npm run build-storybook

プロジェクトのルートにstorybook-staticフォルダーが生成され、選択した静的ホスティングサービスにアップロードする準備ができているすべてのファイルが含まれます。 npxおよびhttp-serverを使用してローカルで試すこともできます。

$ cd storybook-static
$ npx http-server

📙終わり! Storybookの使用法について詳しくは、公式ドキュメントをご覧ください。