Angular 版 Intro to Storybook の日本語訳を更新して思ったこと
本稿はAngular Advent Calendar 2023 21日目の記事です。
20日目の記事は@t-kawamura1の「2年前の自分に送る!べからず集」でした。
概要
知識のアップデートも兼ねてAngular版Intro to Storybookの日本語訳を更新しました。更新差分を見て、こんなことできたらいいなと思ったことをまとめました。
対象読者
- Storybookを触ったことがあり、チュートリアルにある基礎知識は理解している人
翻訳した理由
Storybook が 6.3 系の頃、自社内で Storybook の導入を担当していました。自分 1 人だけでなく同僚も Storybook の知識をキャッチアップできるよう、Intro to Storybook という Storybook のガイドを日本語訳しました。
Angular 向け Storybook のチュートリアルを日本語訳しました
その後 7 系へのメジャーアップデートがあり、色々と面白いそうなアップデートが入ったのを小耳に挟みました。知識のアップデートがてら、日本語訳の更新を買って出ました。しかし娘が産まれるなど私生活で大きな変化があったこともあり、ズルズルと先延ばしにしてしまい気づいたら 1 年経ってしまいました。コレではいかん、自分の中で締切を作ろうということで、言い方は悪いですがアドベントカレンダーをきっかけとして使わせていただきました。
かなり記事の公開にギリギリになってしまいましたが、翻訳の更新が一旦終わりました。他の日本語ネイティブによる校正などが終わっていないため main ブランチにはマージされていませんが、チュートリアルのレポジトリのフォークから更新後の訳を確認できます。
チュートリアルで大きく変わっていた点
細々とした点は他にも変わっていましたが、「結局 Storybook で何ができるの?」という内容に限ると主だった変更はplay 関数とtest-runnerでしょうか。
6.3 の時点では単体で UI コンポーネントを表示するためのライブラリだった Storybook が、これらの機能が入ることで UI だけではなくロジックまで含めたテストの実行環境に変わりつつあるという印象です。Jest と Testing Library を Storybook 経由で使うことができるようになるので、工夫とアイディア次第では色々なテストに応用できそうです。個人的に出来たら面白そうだなと思っているのは以下の 2 つの使い方です。
- Markuplint を Storybook 上で実行
- Appium/Webdriver.IO と Play 関数で処理の共通化
試してみたいこと
Markuplint を Storybook 上で実行
業務ではMarkuplintを使いながら HTML のマークアップをしています。html ファイルに対して実行する静的解析なので、コンポーネントを UI として組み合わせたときに正しいマークアップかというチェックはそのままでは出来ません。例えば以下の例のようなマークアップの問題を(Markuplint に限らず)静的解析で検知するのは困難だと思います。
import { Component } from '@angular/core';
@Component({
selector: 'app-breadcrumbs',
template: '<nav>パンくずリスト</nav>',
standalone: true,
})
export class BreadcrumbsComponent {
/** 略 */
}
@Component({
selector: 'app-global-nav',
template: '<nav>グローバルナビゲーション</nav>',
standalone: true,
})
export class GlobalNavComponent {
/** 略 */
}
@Component({
selector: 'app-top',
// 1つのページにnavが複数あるので、スクリーンリーダーでスキップをするときなどにどちらがパンくずでどちらがグローバルナビゲーションか区別ができない
template:
'<header><app-breadcrumbs/></header><main>トップページ</main><footer><app-global-nav/></footer>',
standalone: true,
imports: [BreadcrumbsComponent, GlobalNavComponent],
})
export class TopComponent {
/** 略 */
}
TopComponent を Storybook 上で描画し、その DOM に対して Markuplint を実行するとどうでしょうか。
DOM は
<header>
<app-breadcrumbs><nav>パンくずリスト</nav></app-breadcrumbs>
</header>
<main></main>
<footer>
<app-global-nav><nav>グローバルナビゲーション</nav></app-global-nav>
</footer>
のような階層になります。この形であれば、同一ページ上に特定のランドマークロールが複数あるにも関わらず、一意のラベルを付与していないことを検知できるようになります(landmark-roles)。このように単一のコンポーネントに対しては実施できなかったチェックを Story 上でできるようになるのではと期待しています。
Appium/Webdriver.IO と Play 関数で処理の共通化
公式ドキュメントにCypress で Story を再利用する例があります。E2E で Story を使えれば工数を大きく削減できそうですが、今の仕事ではIonicを使ったハイブリッドアプリを作っています。Web アプリとしてだけではなく、Android・iOS アプリとしてビルドしたバイナリも Story を使ってテストしたいです。
Ionic が公開している E2E のサンプルでは、Appium と Webdriver.io を使ってテストしています。そしてWebdriver.ioにはTestingLibraryをラップするライブラリがあります。関数を import する元を@testing-library/webdriverio
にするか@storybook/testing-library
にするかをビルドのときに差し替えることができれば、Storybook の Play 関数と E2E の大部分を共通化できるのではないでしょうか。これはいま絶賛検証中でして、結果が分かり次第記事にしようと思います(他の人も試したら結果を教えて欲しい)
まとめ
チュートリアルだけでなく公式ブログなどもこの機会にざっと見返してみましたが、上記が v7 の Storybook で出来るようになった主なポイントのようです。web というプラットフォームにある幅広いツールとの連携が出来るようになったのは便利ですが、一方で今までこれらのツールでしていたことが便利に出来るようになった以上の変化はなかったと思います(何か私が見落としていて、今までのツールだど出来なかったこんなことが出来るようになったよ!というのがあればコメント欄などで教えていただけると嬉しいです)。
Storybook がないとできない訳ではないけれど、UI を見ながら単体テストを書いたりAddon Interactionsでデバッグしたりなど、ツールの組み合わせで生まれるシナジーが導入・メンテのコストを上回るかどうか。この点が Storybook を使うか使わないか(あるいは使うのをやめるか)の判断で 1 つポイントになりそうです。
明日は@seapolisさんがSSRについて書いてくれます。
Discussion