チーム開発に効く Angular x Storybook 6

6 min read読了の目安(約5400字

Angular Advent Calendar 2020 24日目の記事です。

Angular を使ってチーム開発するときに Storybook を使うと捗るという話です。今年8月に登場した Storybook 6.0 で大幅に使い勝手が良くなっているので、そこについても紹介します。

Storybook について

開発者が複数人いて、デザイナーもいる環境だとします。昨今はデザインシステムの登場で、デザインの時点でコンポーネントが意識されていることもあります。そうなってくると、コンポーネント単位で見た目を確認したいという需要が出てきます。そこで役に立つのが Storybook です。

Storybook は公式には「UIコンポーネント開発ツール」と表現されています。言葉で説明より先に、まずは Docs の Get Started > Examples > Storybook Design System を見てみてください。この例は React のストーリーなのですが、Angular で作ってもだいたい一緒です。

左側の Button の Basic を選ぶと、まず Docs の画面が開きます。

Storybook Docs

ボタンコンポーネントの単体について、色々なケース(ストーリーと言います)での見た目を確認できます。また、コンポーネントの Input の名前、コメントが分かりやすく表でまとまっています。この例では値を操作できるのですが、Angular だと次に示す Canvas の画面からでないと操作できません。

Canvas のタブに切り替えると、個々のストーリーを確認できます。

Storybook Canvas

先ほどの Docs タブと違って、このタブでは Angular でも Input の値を操作できます。また、上部にいくつか見た目の確認に役立つボタンがあります。背景を暗くしたり、グリッドを表示したり、モバイル端末の画面サイズにしたりすることができます。

だいたいの機能を紹介したところで、開発でどのように Storybook が役に立っているかを紹介します。

  • 実際の画面操作ではなかなかたどり着けない画面のデザインを整えるとき。
    • Storybook がないとき:その画面にたどり着くのが大変なので、仮のルーティングを設けてそれを表示して開発する。仮で作って後から消すのが地味に手間。
    • Storybook があるとき:その画面のコンポーネントのストーリーを作れば問題解決!Storybook を公開しておけば、開発者に限らず、誰もが好きなときにその画面の表示を確認できます。
  • 完成したコンポーネントをデザイナーに確認してもらうとき。
    • Storybook がないとき:状態別のスクショを撮ってデザイナーに確認してもらうなどする。スクショで確認というなんともいえないイマイチ感。(スクショのほうが都合がいいこともあるけど)
    • Storybook があるとき:ストーリーを作ってそれを確認してもらえば、見た目だけでなく動作まで確認してもらえます。

このように、開発にも役に立つし、開発者とデザイナーの架け橋としても役に立ちます。また、開発者同士の間であっても役に立ちます。個人的にはコードレビューが捗ると感じています。仕事では、デザイナーが zeroheight でコンポーネントのデザインをまとめているのですが、そこに Storybook を埋め込むといった運用もしています。

今年出た Storybook 6 について

今年 (2020年) 8月には Storybook 6.0 がリリースされました。最新版は 6.1 ですが、大差ありません。6.0 でどう変わったのかは Migration Guide に色々あるのですが、このバージョンは以前 Storybook を使ったことがあるけど最近はさっぱり……という方にぜひ目を向けてほしいバージョンです。いくつか紹介します。

  • Storybook 上で Input を操作して見た目を確認するには addon-knobs でコードを書く必要がありましたが、6.0 では自動化されました!何も書かなくていいんです。ストーリーの書き換えは必要ですが、ほとんどがコードの削除で、今後のストーリー保守が大幅に楽になります。
  • addon-actions も不要です。
  • とりあえず @storybook/addon-essentials さえ入れておけば大丈夫、という状況になっています。これで .storybook/main.js やら package.json やらがスッキリします。

かんたんな使い方を紹介

トップページの "Get Started" ボタンをクリックし、"Framework" から "Angular" を選びましょう。すると Introduction to Storybook for Angular が開きます。

Install のところは、3行で書けば次のとおりです。

「そこに Angular プロジェクトがあるじゃろ?」
npx sb init を実行するじゃろ?」
「これで終わりじゃ」

sb init が済むといくつかのファイルが現れます。

  • .storybook: Storybook の設定ファイルなどです。
  • src/stories: サンプルのコンポーネントとストーリーです。
    • あくまでサンプルなので、削除しても構いません。
    • コンポーネントを開くと、エディタで赤線だらけになりますが、たぶん NgModule に属していないからです。
    • button.component.ts などは、見慣れたコンポーネントです。Input や Output にしっかりコメントが書いてありますが、これがポイントです。ここに書いたコメントが Storybook の Docs に表示されます。
    • Button.stories.ts などがストーリーです。

ストーリーのコードを見ていく前に npm run storybook を実行して Storybook を立ち上げておきましょう。実際動いているところと見比べていくと理解しやすいので。

ここまでのソースと、それを npm run build-storybook して GitHub Pages で見られるようにしたものを置いておきます。

Button のストーリーについては Button.stories.ts に書いてあります。コメント多めに解説すると、このようになっています。

export default {
  // 左側のナビゲーションでの階層、名前を指定する
  title: 'Example/Button',
  // ストーリーの対象となるコンポーネント
  component: Button,
  argTypes: {
    // 文字列として入力するのではなく、カラーピッカーで選べるようにする
    backgroundColor: { control: 'color' },
  },
} as Meta;

今回は依存のないシンプルなコンポーネントなのでこれだけのコード量で済みます。サービスやモジュールへの依存がある場合は Writing Stories > Introduction を参考にmoduleMetadata を書いてください。単体テストで configureTestingModule するノリです。

次は、コンポーネントの各状態のストーリーを書くためのテンプレートです。

const Template: Story<Button> = (args: Button) => ({
  component: Button,
  props: args,
});

ちょっとおまじないっぽさがありますが、Storybook 6.0 で登場した Args によるもので、これによってコード量が非常に少なくなります。最後は各状態のストーリーです。

export const Primary = Template.bind({});
Primary.args = {
  primary: true,
  label: 'Button',
};

テンプレートを用意したおかげで、とても簡潔です。Button コンポーネントの Input に args を指定したストーリーです。

これだけで、次のような Docs, Canvas の見た目が完成します。コンポーネントには、こういう Input があって、こういう型で……といった指定は不要です。簡単便利!

Docs

Canvas

Angular で Storybook を使うときには、いくつか注意点があります。

  • コンポーネント自体や、そのプロパティの増減は、保存しただけでは Storybook に反映されません。
    • 別のターミナルを開いておいて npm run docs:json を手動で叩けば反映されます。
  • React の例では表示されていたコンポーネントの入力のデフォルト値が Docs に表示されていましたが、 Angular だと反映されません。
  • ここまでの話で何度かふれましたが、Docs タブで Input の値を変えても見た目に反映されません。Canvas タブを使いましょう。

おわりに

  • Storybook を使うとチーム開発が捗ります。
  • Storybook 6.0 で大幅改善されているので、以前使ってた方はぜひアップデートを。
  • Angular から Storybook 6.0 を使う方法を紹介しました。

参考にしたサイト: