前回の記事ではHRMOSのDesign Systemの導入背景の紹介をしました。
本日はそのDesign Systemがどのように開発・運用されているのかを紹介したいと思います。
開発体制
Design Systemの開発はデザイナー、エンジニアが1つのチームとして開発を行っています。
開発のポイントとしては以下のとおりです。
- デザインタスク、実装タスクなどすべてのDesign Systemのタスクは1つのバックログで管理
- 隔週に1度、やることの計画、やったことの確認をチーム全員で行う
- チームメンバーは全員兼務なので、極力MTGを増やさないよう、非同期でのコミュニケーションをメインにしている
この体制になった背景として、当初はDesign System開発がデザイナーとエンジニアで分断されていたことにあります。
デザインとエンジニアリングでそれぞれ別のバックログをもち、それぞれ別のサイクルで動いていたことで以下のような問題が発生していました。
- エンジニア側からはデザインの状況がわからず、実装可能なものが理由がわからない状態で振られてくる
- デザイナー側からは実装の状況がわらかず、デザインしたものがいつ実装されるのかわからない
この状況を解決するために、
- バックログを1つにして、デザイナー、エンジニアともに同じものを見るように
- チーム全員が参加する会議体をつくり、状況と今後の確認を定期的に行う
という対応を行い、今の形になりました。
Design Systemの実装
Design Systemをプロダクトに反映させるために、様々な実装上の工夫を行っています。
設計レビュー
新しいコンポーネントを実装する際は必ず、そのコンポーネントの実装上の使い勝手が悪くないかについて、ある程度の共通認識を持つために、設計レビューを行っています。
Design SystemはHRMOSの様々なモジュールで利用できるように、npmのライブラリとして提供しています。複数のモジュールで利用するものを簡単に変更ができないため、できるだけ修正が発生しないよう設計を丁寧にしたいという理由と、実装してからの手戻りを最低限にしたいという理由でこのフローをいれています。
ここで確認するのは以下の点です。
- コンポーネント、プロパティ名が適切かどうか?
- HTMLの構造が適切かどうか?
- コンポーネントの粒度が適切かどうか?
- コンポーネントに必要なプロパティは過不足なく存在するか?
実装のアウトプットとしてのStorybook
実装のアウトプットとしてStorybookでコンポーネントガイドを作成し、これをNetlifyというホスティングサービスで公開しています。
コンポーネントの表示だけでなく、プロパティ値の詳細や変更、HTML構造の表示などを簡単な記述でできるので重宝しています。1
NetlifyはPull Requestごとにホスティングできる Deploy Preview という機能があり、この機能を使ってmainブランチへのマージ前にデザイナーにアウトプットを簡単に確認してもらえるというメリットもあります。2
コントリビュートに対する品質保証
まだまだ体制が不十分ではあるのですが、Design System開発チーム外のコントリビュートも歓迎しています。
意図しない変更が入らないようにするため、コントリビュートに対して、必ずDesign System開発チームのレビューが通るようにしてるのですが、そのためにGitHubのコードオーナーという機能を使ってコントリビューターが誰にレビューを依頼するか意識しなくても済むようにしています。
この機能はファイルに対して、所有者(複数人、チームも可)を設定すると、そのファイルが変更のあるPull Requestが作られると自動的に所有者に対してレビューがリクエストされるというものです。
Branch protection ruleの設定で、コードオーナーのレビューを必須にすれば、コードオーナーのレビューが通らないとマージできなくなります。
様々な自動テスト
Design Systemはライブラリとして、複数のモジュールに提供しているため、バグが様々なモジュールに影響する可能性があります。特に、意図しないところにバグがでるデグレが一番気づきにくいため、このデグレに気づける仕組みを複数いれています。3
また、これらの仕組みはリファクタリングの際の動作確認にも役立っています。
Cypressによるインタラクションテスト
Storybookに対して、トーストやモーダル、ツールチップなど、何かのアクションきっかけに動作するUIを中心にCypressによるインタラクションテストを行っています。
Cypressはブラウザ上の操作をエミュレートし、その結果が想定通りかどうかをチェックできるe2eテストのフレームワークです。
代替ツールはいくつかあるのですが(TestCafeなど)、導入事例が多く、テストの書きやすさ、確認のしやすさなどを加味してCypressを採用しました。
Chromaticによる画像回帰テスト
Storybookの各コンポーネントのUIの変更前のキャプチャと変更後のキャプチャを比べることで、デグレを検知することができるChromaticというサービスを利用しています。
画像回帰テストはref-suitなど、便利なツールがあるのですが、導入が手軽な点に惹かれて採用しました。4
リリースの自動化
semantic-releaseとGitHub 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はマージができないようにしています。
また、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でリリースされるか確認後、リリースするというフローをとっています。
最後に
ここまで紹介した様々な工夫により、Design Systemの開発・運用をより効率化してきました。
しかし、HRMOSのこれからの成長を考えると、Design Systemとして取り組むべき課題は沢山あります。
- Design Systemが提供したい体験に歪み
- Design Systemの適用範囲の拡大につれ、最初は小さかった不整合が徐々に大きくなりつつある
- ⇒ インセプションデッキの作成など、Design Systemのコアとなる部分の見直しを開始している
- デザインと実装の不一致
- コンポーネントやプロパティの命名や粒度がデザインと実装で異なっている
- ⇒ デザイントークン、コンポーネントの粒度や抽象度を改めて整備したい
- 短期だけではない、中長期的な計画の必要性
- スプリントサイクルに基づく計画は立てているものの、より中長期的な計画は立てられていない現状
- ⇒ クォーター毎に振り返りを実施、製品ロードマップや利用者の声をもとに、長期のものは組織目標に組み込む流れにしたい
- コントリビュート体制が不明確
- コントリビュートの体制が不明瞭で実質Design System開発チームが開発のほとんどを担当してしまっている
- ⇒ Design System開発チーム外のエンジニアも積極的に関与できるようにして、HRMOS全体でDesign Systemを作っていくという雰囲気をつくりたい
- Design Systemの実装であるライブラリの肥大化
- 使わないComponentも含めてインストールする必要があり、利用側のアプリケーションのバンドルサイズを圧迫している
- ⇒ 適当な単位でパッケージを分割し、使用者が使いたいものだけ使えるようにしたい
これらの課題を一緒に解決していける仲間を募集中です!
少しでも興味をお持ちいただいた方は、このページの下部にあるバナーよりご応募よろしくおねがいします!