前回の記事ではHRMOSのDesign Systemの導入背景の紹介をしました。
本日はそのDesign Systemがどのように開発・運用されているのかを紹介したいと思います。

開発体制

Design Systemの開発はデザイナー、エンジニアが1つのチームとして開発を行っています。
開発のポイントとしては以下のとおりです。

backlog
数あるバックログアイテムから2週間でやるものをスプリントバッグログに登録している

この体制になった背景として、当初はDesign System開発がデザイナーとエンジニアで分断されていたことにあります。
デザインとエンジニアリングでそれぞれ別のバックログをもち、それぞれ別のサイクルで動いていたことで以下のような問題が発生していました。

この状況を解決するために、

という対応を行い、今の形になりました。

Design Systemの実装

Design Systemをプロダクトに反映させるために、様々な実装上の工夫を行っています。

設計レビュー

新しいコンポーネントを実装する際は必ず、そのコンポーネントの実装上の使い勝手が悪くないかについて、ある程度の共通認識を持つために、設計レビューを行っています。
Design SystemはHRMOSの様々なモジュールで利用できるように、npmのライブラリとして提供しています。複数のモジュールで利用するものを簡単に変更ができないため、できるだけ修正が発生しないよう設計を丁寧にしたいという理由と、実装してからの手戻りを最低限にしたいという理由でこのフローをいれています。

ここで確認するのは以下の点です。

interface review
想定の使い方やコンポーネント名などを記載し開発者間で共通認識をとる

実装のアウトプットとしてのStorybook

実装のアウトプットとしてStorybookでコンポーネントガイドを作成し、これをNetlifyというホスティングサービスで公開しています。
コンポーネントの表示だけでなく、プロパティ値の詳細や変更、HTML構造の表示などを簡単な記述でできるので重宝しています。1

storybook
Storybookにはコンポーネントのすべての状態を表示している

NetlifyはPull Requestごとにホスティングできる Deploy Preview という機能があり、この機能を使ってmainブランチへのマージ前にデザイナーにアウトプットを簡単に確認してもらえるというメリットもあります。2

design review
実装が終わったらStorybookのURLをつけてデザイナーに確認を依頼している

コントリビュートに対する品質保証

まだまだ体制が不十分ではあるのですが、Design System開発チーム外のコントリビュートも歓迎しています。
意図しない変更が入らないようにするため、コントリビュートに対して、必ずDesign System開発チームのレビューが通るようにしてるのですが、そのためにGitHubのコードオーナーという機能を使ってコントリビューターが誰にレビューを依頼するか意識しなくても済むようにしています。

この機能はファイルに対して、所有者(複数人、チームも可)を設定すると、そのファイルが変更のあるPull Requestが作られると自動的に所有者に対してレビューがリクエストされるというものです。

code owner review
コードオーナーが自動的にreviewersに設定される

Branch protection ruleの設定で、コードオーナーのレビューを必須にすれば、コードオーナーのレビューが通らないとマージできなくなります。

branch protection rule
設定でコードオーナーのレビューを必須に

様々な自動テスト

Design Systemはライブラリとして、複数のモジュールに提供しているため、バグが様々なモジュールに影響する可能性があります。特に、意図しないところにバグがでるデグレが一番気づきにくいため、このデグレに気づける仕組みを複数いれています。3
また、これらの仕組みはリファクタリングの際の動作確認にも役立っています。

Cypressによるインタラクションテスト

Storybookに対して、トーストやモーダル、ツールチップなど、何かのアクションきっかけに動作するUIを中心にCypressによるインタラクションテストを行っています。
Cypressはブラウザ上の操作をエミュレートし、その結果が想定通りかどうかをチェックできるe2eテストのフレームワークです。
代替ツールはいくつかあるのですが(TestCafeなど)、導入事例が多く、テストの書きやすさ、確認のしやすさなどを加味してCypressを採用しました。

cypress
コードで書いたとおりにエミュレート・検証ができる

Chromaticによる画像回帰テスト

Storybookの各コンポーネントのUIの変更前のキャプチャと変更後のキャプチャを比べることで、デグレを検知することができるChromaticというサービスを利用しています。

画像回帰テストはref-suitなど、便利なツールがあるのですが、導入が手軽な点に惹かれて採用しました。4

chromatic
細かい差分も検出可能

リリースの自動化

semantic-releaseGitHub Actionの手動実行で好きなタイミングでボタン1つでリリースできるようにしています。

semantic-release

他のツールとは異なり、versionの設定と、GitHub Packageへのリリースをすべて自動でできるので採用しています。
VersioningはSemantic Versioningを元に行っており、この方針を実現するために、 Angular Commit Message Conventionsのフォーマットに従ったPRのスカッシュマージを行っています。

例えば、fix: XXXの修正 というPRをmainブランチマージして、リリースするとパッチバーションが一つ上がります(1.0.0→1.0.1)。
feat: XXXコンポーネントの追加 ならマイナーバージョン(1.0.0→1.1.0)、BREAKING CHANGE がスカッシュマージコミットコメントに含まれていたらメジャーバージョンがあがります(1.0.0→2.0.0)

このフォーマットを守るために、Semantic Pull RequestsというGitHub Appを入れており、このフォーマットに沿っていないPRはマージができないようにしています。

semantic pull request
Semantic Pull Requestが通ることがマージの条件

また、betaバージョン(2.0.0-beta1など)5でのリリースも行うようにしており、破壊的変更があるメジャーバージョンアップが控えている場合は必ずbetaバージョンをリリースし、各モジュールの開発者に事前に動作確認をお願いするということをしています。semantic-releaseならあるブランチのリリースをbetaバージョンとしてリリースするといった設定も簡単に行えます

GitHub Actionによる手動リリース

ライブラリはGitHub Packagesを使って公開しているので、すべてGitHubで完結させるために外部のCIツールを使わずGitHub Actionを使っています。

開発当初はmainブランチにマージされたら自動的にリリースされるようにしていたのですが、想定外のversionでリリースされてしまうことと、頻繁にリリースがされてしまい、利用者に頻繁にupdateをお願いしないといけなくなるというデメリットがあったため、手動でのリリースに切り替えました。

semantic-releaseにはリリースをdry-run(予行練習)できる機能があるので、dry-runで実行して想定通りの変更が想定通りのversionでリリースされるか確認後、リリースするというフローをとっています。

GitHubAction
手動実行時にdry-runするかどうか選択して実行

最後に

ここまで紹介した様々な工夫により、Design Systemの開発・運用をより効率化してきました。
しかし、HRMOSのこれからの成長を考えると、Design Systemとして取り組むべき課題は沢山あります。

これらの課題を一緒に解決していける仲間を募集中です!
少しでも興味をお持ちいただいた方は、このページの下部にあるバナーよりご応募よろしくおねがいします!


  1. Storybook上でだけ動かないとかがたまにあるので、検証用のアプリケーションも別途立てたりはします ↩︎

  2. Netlifyはスループットが悪いので、最近リリースされたCloudfare Pagesに移行するかどうか検討中です ↩︎

  3. 複雑なロジックに対してのユニットテスト(Jest)も入れてますが、ここでは割愛させていただきます ↩︎

  4. その代わり、お金が結構かかります ↩︎

  5. Pre-release versionともいわれ、versionを指定してインストールしない限り、利用者はインストールすることはできない(npm i xxx だけではインストールできない) ↩︎

杉原 碧志
杉原 碧志

HRMOSのフロントエンドが得意なエンジニア。HRMOSシリーズのフロントエンド全般のお仕事をしてます。