LoginSignup
10
8

More than 5 years have passed since last update.

この記事は Angular + Storybook でコンポーネントガイドを作ろう を参考に、インストールのコマンドや設定をメモしたものです。

Storybook
https://storybook.js.org/

環境

  • macOS High Sierra
  • yarn v1.6
  • node v8.10
  • @storybook/angular v3.4.3
  • @angular/cli v1.7.4

Storybook のインストール

npm / yarn どちらでもインストールできます。両方試した結果 yarn のほうがスムーズだったため、こちらを使う事にしました。

私の環境には yarn がインストールされていなかったため homebrew で入れました。

$ brew install yarn

一発目はエラーで失敗したのでリトライ。

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools),
missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
Error: Failure while executing: git config --local --replace-all homebrew.private true

$ xcode-select --install
$ xcode-select: note: install requested for command line developer tools

$ brew install yarn
$ which yarn

/usr/local/bin/yarn

まず Angular のプロジェクトを作成します。

$ ng new learn-storybook
$ cd learn-storybook

Storybook のコマンドラインツールをインストールします。

$ yarn add @storybook/cli

【参考】 node 9系だと SyntaxError: Unexpected token ( in JSON at position 0 というエラーでコマンドが完了しなかったので、node 8 (npm 5.6) を使う事にしました。

Storybook の Angular プラグイン的なものをインストールします。

$ yarn add @storybook/angular babel-core

Storybook を作成します。

$ yarn run getstorybook

# デモページで使われるアドオンもインストール
$ yarn add @storybook/addon-notes 
$ yarn add @storybook/addon-links
$ yarn add @storybook/addon-actions

package.json を開くと storybook / build-storybook という2つのスクリプトが追加されています。Storybook の設定は .storybook ディレクトリに配置されるため、このディレクトリが読み込まれるよう設定します。

- "storybook": "start-storybook -p 6006",
+ "storybook": "start-storybook -p 9001 -c .storybook",
"build-storybook": "build-storybook"

Storybook のファイルが ng serve の実行を妨げないように設定を追加します。

// src/tsconfig.app.json

{
+  "exclude": [
+    "stories",
+    "**/*.stories.ts"
+  ]
}

これでインストールは完了です。
Storybook を起動してデモページを開いてみましょう。

$ yarn run storybook

ブラウザで http://localhost:9001 を開き Welcome to storybook が表示されていれば成功です。表示が確認できたら Ctrl + C で終了します。

スクリーンショット 2018-04-30 21.57.27.png

Storybook にコンポーネントを追加

デモページにはあらかじめいくつかのコンポーネントが表示されています。自分で作ったコンポーネントを追加してみましょう。

まず適当なコンポーネントを作成します。

$ ng generate hello-button
// src/app/hello-button/hello-button.component.ts

import { 
+ Input,
  Component, 
+ EventEmitter,
  OnInit,
+ Output,
} from '@angular/core';

@Component({
  selector: 'app-hello-button',
  templateUrl: './hello-button.component.html',
  styleUrls: ['./hello-button.component.css']
})
export class HelloButtonComponent implements OnInit {
+  @Input() name: string;
+  @Output() hello = new EventEmitter<string>();

  constructor() { }

  ngOnInit() {
  }

+  click() {
+    this.hello.emit(`Hello ${this.name}`);
+  }

}
// src/app/hello-button/hello-button.component.html

- <p>
-  hello-button works!
- </p>

+ <button type="button" (click)="click()">
+ Hello {{name}}!
+ </button>

こんな感じのコンポーネントです。

<hello-button name="foo"></hello-button>
  • <button>Hello foo!</button> のように展開される
  • クリックすると hello イベントが発火し Hello foo! を受け取る事ができる

ストーリーの作成とコンポーネント追加

Storybook のソースコードは index.stories.ts に記述されています。
ここに hello-button コンポーネントを追加してみます。

// src/stories/index.stories.ts

+ import { HelloButtonComponent } from '../app/hello-button/hello-button.component';

+ storiesOf('Hello Button', module)
+   .add('with name', () => ({
+     component: HelloButtonComponent,
+     props: {
+       name: 'foo',
+     },
+   }))
;

storiesOf は Storybook に新しいストーリー Hello Button を追加し、add はストーリーにコンポーネントを追加します。props には @Input に値を渡すための key/value を記述します。

再び Storybook を起動してみましょう。
Hello Button という見出しが追加され、展開すると with name というタイトルが現れるはずです。

$ yarn run storybook

スクリーンショット 2018-04-30 22.19.29.png

コンポーネントのイベントを拾う

hello-button コンポーネントは hello イベントを発火する機能を持っています。
Storybook で発火したイベントを拾ってみましょう。

// src/stories/index.stories.ts

storiesOf('Hello Button', module)
  .add('with name', () => ({
    ...
  }))
+ .add('with action', () => ({
+   component: HelloButtonComponent,
+   props: {
+     name: 'bar',
+     hello: action('clicked!')
+   },
+ }))

ソースコードを保存するとブラウザが自動でリロードし、Hello Button の見出しの下に with action というタイトルが現れます。

ボタンをクリックするとページ下部の ACTION LOGGER タブに clicked! が表示されます。

1.gif

ACTION LOGGER への出力

Storybook にはいろいろなアドオンが存在します。Angular のデモページはデフォルトで actions / links / notes の3つのアドオンが読み込まれています。

// .storybook/addons.js

import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import '@storybook/addon-notes/register';
// src/stories/index.stories.ts

import { withNotes } from '@storybook/addon-notes';
import { action } from '@storybook/addon-actions';
import { linkTo } from '@storybook/addon-links';

actions アドオンをインポートすると action 関数を利用できます。
action 関数は受け取った引数を ACTION LOGGER タブに出力します。

さきほどソースコードに追加したこの部分ですね。

props: {
  hello: action('clicked!')
}

NOTE への出力

notes アドオンを利用すると NOTE タブに任意の HTML を出力する事ができます。

// src/stories/index.stories.ts

storiesOf('Hello Button', module)
  .add('with name', () => ({
    ...
  }))
+  .add('with note', withNotes(`
+    <h3>Notes</h3>
+    <span>sample text</span>
+    `)(() => ({
+      component: HelloButtonComponent,
+      props: {
+        name: 'hoge',
+      },
+    })
+  ))

スクリーンショット 2018-04-30 22.50.10.png

アドオンの追加

デフォルト以外のアドオンを読み込んでみましょう。
Knobs を利用すると Storybook 上で入力したテキストをリアルタイムにコンポーネントに反映させる事ができます。

$ yarn add @storybook/addon-knobs
// .storybook/addons.js

+ import '@storybook/addon-knobs/register';
// src/stories/index.stories.ts

+ import { text, withKnobs } from '@storybook/addon-knobs/angular';

storiesOf('Hello Button', module)
+ .addDecorator(withKnobs)
  .add('with name', () => ({
    ...
  }))
  .add('with name', () => ({
    component: HelloButtonComponent,
    props: {
-     name: 'foo',
+     name: text('name', 'foo')
    },
  }))

ブラウザをリロードすると追加の Knobs アドオンが有効になります。

1.gif

他にもいろいろなアドオンが Storybook 公式ページで紹介されています。

Storybook Addon Gallery
https://storybook.js.org/addons/addon-gallery/

静的ページの出力

build-storybook コマンドを使うと Storybook を静的ページとして出力する事ができます。出力先はルートディレクトリ直下の storybook-static です。

$ yarn run build-storybook
$ open storybook-static/index.html

ディレクトリ構成

Storybook は既存の Angular プロジェクトに後付けで追加する事もできます。Storybook によって追加されるディレクトリ・ファイルは以下に示す ●印 の部分です。

├── .storybook ●
│   ├── addons.js ● // アドオン
│   └── config.js ● // Storybook の読み込み
├── node_modules
├── package.json
├── src
│   ├── app
│   ├── stories ●
│   │   └── index.stories.ts ● // Storybook を記述するファイル
├── storybook-static ● // build-storybook で出力される静的ページ
│   ├── favicon.ico ●
│   ├── iframe.html ●
│   ├── index.html ●
│   └── static ●

おわり

複数プロジェクトで利用するオリジナルのコンポーネントを開発しているのですが、使い方を説明するために demo.html にサンプルを載せて GitHub wiki にドキュメントを書いて...という事をせっせと行っていました。これを便利に代行してくれるのが Storybook ではないかと思います。

まだ Angular 未対応のアドオンもちらほらあるようですが、demo.html みたいな泥臭い作業をせっせとこなすより、新しいものをワクワクしながら使いたいですね!

10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8