この記事の概要
- デザインシステム 『Tsukuri』の Web 向け実装『Tsukuri for Web』を開発中です
- 変更しやすくするために構成要素の依存関係を考慮した構造を検討しました
- コンポーネントの実装は Web Component を利用し、Vue.js と React にも対応します
- アイコンやデザイントークンに対応する実装は Figma から取得したリソースを元に生成します
1. はじめに
2022/08/16 に入社しました、Web フロントエンド開発を中心に行っている寺島です。
私は入社してから現在に至るまで、アンドパッドのデザインシステム 『Tsukuri』 の Web 向け実装である 『Tsukuri for Web』を開発しています。
この記事では以下について紹介します。
- Tsukuri および Tsukuri for Web の背景
- 現在行っている開発のベースとなる方針
- Tsukuri for Web の全体像について
上記の内容を通して以下を満たすことを目的としています。
- デザインシステムの Web 向けの実装に対して興味がある開発者やデザイナーに対して、 Tsukuri for Web における方針決定などのポイントを共有し役立ててもらうこと
- このような情報を通してアンドパッドに興味をもってもらうこと
また、この記事に続くいくつかの記事を作成する予定です。そこでは、実装に関する内容などについてを共有することを予定しています。
2. 背景
現在アンドパッドではデザインシステム Tsukuri を構築しています。
デザインシステムは、企業のビジョンなどから導かれるデザインの原則や、それらを実装するために必要なリソース群を指すものです。
デザインシステムは非常に広範な対象を取るものですが、アンドパッドでは、自社で開発・運営している SaaS プロダクトである ANDPAD で利用するためのリソース整備を中心に取り組んできています。
この取り組みについては以前のイベントやインタビュー記事の中で、デザイナーのかわかみが詳しく紹介しています。 logmi.jp
このデザインシステムの Web 向け実装は私の入社以前から始まっており、『tsukuri-css』 というライブラリを構築していました。 tsukuri-css はその名の通り、デザインシステムを CSS や CSS のメタ言語である SCSS で実装したものです。
ANDPAD は Vertical SaaS であり、様々なプロダクトで構成されています。そして、ANDPAD の Web フロントエンドはプロダクトによって Vue.js や React など、利用しているライブラリが異なります。 これらライブラリに依存しない CSS による実装を行うことで、アンドパッドの持つプロダクトすべてに導入できるようにすることを目指しました。
tsukuri-css はプロダクトを開発しているメンバーが兼任する形で構築しており、そのメンバーが担当しているプロダクトを中心に一部のプロダクトで導入が行われている状態でした。
この取り組みについても、以前のイベントで Web フロントエンドエンジニアの小泉が詳しく紹介しています。 logmi.jp
その後、私が Tsukuri の Web 向け実装を専任で行うメンバーとして入社しました。 この時点で、tsukuri-css の構築を開始した時点から少し時間が経ち、ANDPAD から Internet Explorer (IE) のサポートをドロップするという意思決定が行われたこともあったので方針を再検討し再スタートすることとしました。
3. 方針
方針を検討する時点で、構築中のデザインリソースとして以下が存在していました。
- UIコンポーネントのデザイン・ふるまいの仕様
- アイコン
- デザイントークン (色・サイズ・タイポグラフィなどを定義したもの)
Tsukuri for Web ではこれらを Web フロントエンド開発で利用可能な実装に落としこむことになります。 このセクションではどのように実装をしていくかの大きな方針について記載します。
3.1. 方針検討にあたって重視した点
方針検討にあたって以下の点を重視しました。
- 最低限 Vue.js / React いずれのプロダクトでも利用できるようにする
- Tsukuri for Web を利用することがプロダクト開発を妨げることはせず、より効率的に開発できるようにする
- デザインシステムでの変更を可能な限り迅速に反映できるようにする
- Web はフロントエンド開発の基盤となりうるため安定した技術を用い変更しやすい作りにする
これらは相互に関係します。それぞれについて以降で説明します。
3.1.1. Vue.js / React いずれのプロダクトでも利用できるようにする
これは最重要の要件です。 Tsukuri for Web は Web フロントエンドで利用できるデザインシステム Tsukuri の実装を提供するものです。
そしてデザインシステム Tsukuri は一貫したデザインを通してよりよいユーザ体験を提供することが目的の一つです。
従って、特定のプロダクトで利用ができない状態になれば Tsukuri for Web の存在意義を問われることになります。
前述の通り tsukuri-css はこの要件を満たす上で適切なアプローチでした。
3.1.2. Tsukuri for Web を利用することが開発を妨げることはせず、より効率的に開発できるようにする
前述の通り Tsukuri for Web を構築し利用することは、サービス利用するユーザの体験を向上させることが目的です。
ここで、Tsukuri for Web を利用し、プロダクトへの導入を進めるのは基本的に各プロダクトの開発者です。 従って、Tsukuri for Web が開発者体験を損なうようでは目的の達成はできません。
また、ユーザ体験を高めるために、プロダクトの機能追加が遅れることも適当ではありません。これらは両輪となってプロダクトの価値を高めるものであるべきです。
Tsukuri for Web を構築する目的を達成するためにも Tsukuri for Web それ自体や、その他のサポートを通して、開発者体験を高めるものであるべきと考えました。
3.1.3. デザインシステムでの変更を可能な限り迅速に反映できるようにする
デザインシステムの構築が進めば、デザイナーはデザインシステムのリソースを用いて UI のデザインを行います。 この時、 Tsukuri for Web にデザインシステムの内容が反映されていないと、開発者は Tsukuri for Web を利用することが難しくなります。
また、デザインシステムの構築は反復的に行われます。デザインを進めてフィードバックを得ることで新たなパターンや表現を発見して、継続的に更新されていきます。
可能な限り早くデザインシステムの変更を反映することは、プロダクト開発を後押しし、Tsukuri for Web を導入しやすくすることにつながります。
3.1.4. Web フロントエンド開発の基盤となりうるため変更しやすい作りにする
プロダクト間で一貫した体験を提供するために最終的にはほとんどのプロダクトが Tsukuri for Web を利用することを目指します。 したがって、Tsukuri for Web は将来的にすべてのプロダクトの基礎になりうるソフトウェアと言えます。
このようなソフトウェアに大きな破壊的な変更が発生するとメインのプロダクト開発が大きく滞ります。 最近だと Vue.js のメジャーバージョンによる影響が例として挙げられると思います。
そのため、破壊的を変更が少なく保ちつつ、様々な環境の変化に対応しつつ機能の追加や改修を行えるような設計とすることが求められます。
3.2 決定した方針
上記の内容を踏まえて検討を行い以下のような方針としました。
- コンポーネントの実装には Web Component を利用する
- Web Component からコンポーネントのメタ情報を生成する
- 生成したメタ情報をもとに Vue.js と React それぞれのコンポーネントを作成してライブラリとして提供する
- アイコンはコード上では SVG ファイルとして管理する
- SVG をベースに Vue.js や React のコンポーネントを作成してライブラリとして提供する
- SVG ファイルの取得元やその利用についての責任を分けるようにする
- デザイントークンはコード上では style-dictionary で利用されているデザイントークン形式で管理する
- 管理しているデザイントークンを利用して CSS などの形式のファイルを作成してライブラリとして提供する
- デザイントークンの取得元やその利用についての責任を分けるようにする
3.2.1. コンポーネントの実装には Web Component を利用する
tsukuri-css はフレームワークに依存しないデザインシステムの実装として CSS による実装を選択しました。 しかし、デザインで表現される内容にはユーザとのインタラクションが含まれることがあります。既存のUIコンポーネントライブラリに対して CSS を適用して対応できればよいですが、そうでなければ各プロダクトの開発者がその部分を実装することになります。
加えて、意図したビジュアルや a11y のサポートを実現するためには適切なマークアップやキーボードイベントのハンドリングなどがセットとなります。 これを間違えれば結果として体験を損なう結果にもなりかねないので、その部分も含めて Tsukuri for Web でサポートするのが望ましいです。
Web Component は独自の UI コンポーネントを実装するための Web 標準の技術です。 これを用いれば特定のライブラリに依存せずに UI コンポーネントを実装できるため、前述の要求に適合します。
また、 IE のサポートを ANDPAD がドロップしたというのも選択を後押ししています。IE で Web Component を利用するにはポリフィルが必要であり、また、動作も完全ではありませんでした。
加えて ANDPAD のプロダクトの多くは SPA として実装されており SSR を必ずしも必要としないという点も判断をする上で大きい要素でした。Web Component の SSR は現在対応が進められていますが(例えば、Astro などの SSR / SSG を行うソフトウェアでは Web Component を構成するライブラリの Lit がサポートされています)、まだ安定して簡便に使えるという状態とは言い難いので、この点は判断のポイントになると思います。
Web Component はそのまま Vue.js や React で利用できます。しかしながら、型情報のサポートをはじめとしてライブラリネイティブなコンポーネントのように使うのは難しいというのが現状です。
先に示した通り、 Tsukuri for Web は開発者体験を損なうものではありたくないという意思があります。そこで Web Component をそのまま提供するだけではなく、各ライブラリで Web Component をラップし、ライブラリネイティブなコンポーネントかのように扱える、ライブラリを構築し提供することとしました。
Web Component の実装に対して、その attribute・event・slot などのメタ情報を記述するスキーマを定義した custom-elements-manifest という仕様と、Web Component の実装を元にこれを出力する @custom-elements-manifest/analyzer というソフトウェアがあります。
ここで得られるメタ情報を元にすることで、内部で Web Component を利用し、Web Component と各種コンポーネントライブラリでの実装のギャップを埋めるコードを機械的に実装できます。
このような方針をとることで、Tsukuri for Web の UI ライブラリは、Web Component のインターフェースを中心として、どのような UI ライブラリでそれを利用するか?ということを選択しやすくなりました。 例えば、Vue.js と React に加えて Svelte を利用したくなればこれに対応する実装を足せばよいです。
(そもそも組織内で様々なライブラリを利用するのがどうか?という点については、これとは独立して大いに議論すべきだと考えています。)
また、デザインシステムの Web 向け実装という性質から各コンポーネントの多くは自己完結しています。この点と、先ほど紹介した、各ライブラリは WebComponent のインターフェースに依存しているという点が合わさることで、各パーツの Web Component をどのように (何を使って) 実装するか?という点も各コンポーネントで独立して選択することもできます。
例えば、当初は Web Component を Lit を使って実装していても、あるタイミングで内部的には Svelte を使いたくなった時には、Web Component のインターフェースを維持していれば特定のコンポーネントだけを内部の実装を変更することが行いやすくなります。
実際にそうするかどうかはともかくとして、そのような自由度を確保しておくということは先に示した Tsukuri for Web に求められることを満たすために重要な特徴です。
3.2.2. アイコンはコード上では SVG ファイルとして管理する
デザインシステム Tsukuri はそのリソースの多くを Figma で作成しています。 Figma で作成されたオブジェクトは SVG 形式で出力することが可能です。また、適切なソフトウェアを利用すれば SVG を入力としてアイコンフォントや各フロントエンドライブラリに対応したコンポーネントを作成することもできます。
上記のようなアプローチは現在広く用いられており、基本的にはこれを採用するという方針です。
しかし、最終的に必要となる各ライブラリネイティブな UI コンポーネントだけでなく、SVG自体もコード上で独立したパッケージとして管理することにしました。そして、各アイコンライブラリに相当するパッケージは、SVG を管理するパッケージを参照するという形をとっています。これによって、各 アイコンコンポーネントのパッケージなどは SVG の出自などに関心を持たないようにしています。
このことは、例えば Figma が利用できなくなった場合でも直接 SVG ファイルを追加・編集することで問題なく開発が維持できることを示しています。 そのようなことが頻繁に発生するとは考えにくいものの、Tsukuri for Web が長期間利用されるであろうソフトウェアであることを考えると、このような場合や、デザインツールを乗り換えたくなった場合に Tsukuri for Web 自体がハードルにならないようにすべきであろうと考えました。
3.2.3. デザイントークンはコード上では style-dictionary で利用されている形式でメタデータを管理する
style-dictionary は JSON 形式で表現されたデザイントークンの情報から CSS やそれのメタ言語などの形式で出力することができるソフトウェアです。 前述のアイコンについてと同様に Figma から何かしらの方法でデザイントークンに相当する情報を style-dictionary の形式で出力し、style-dictionary を用いてソフトウェアの実装に利用できる形式に変換するということがよく行われています。
ここで、この JSON で表現されたデザイントークンのメタ情報をアイコンのSVG と同様にコード上で管理するという方針を取ります。 この方針は先ほどのアイコンの SVG と同様の理由でそのようにしています。
また、コードの生成に style-dictionary を使うかどうかに関わらず、 style-dictionary で用いられているフォーマットはデザイントークンを表現する上で十分な表現力を有していると考えました (値自体や値の参照などが表現できます)。 この形式を中心にすることでデザイントークンのリソースを作成する対象 (Figma など) と、デザイントークンをどのような形式 (CSS や SCSS など) で利用するかを分けて考えることができるようになります。
これに加えて、仮に何らかの理由で style-dictionary が利用できなくなったとしても、自分たちのニーズのみを満たす限定的なものであれば代替品を実装することはそれほど難しくないだろうと考え、この方針としました。
4. Tsukuri for Web の全体像
ここまでの内容を踏まえた Tsukuri for Web 全体のうち主要なものを以下に示します。
図を見てわかるように Tsukuri for Web の主要なアウトプットは以下に依存しています。
- Web Component のメタデータ
- アイコンのSVG
- デザイントークンのメタデータ
先にも触れたとおり、このような構造をとることで、その生成元と生成先がそれぞれ自由度を持たせやすくなります。
例えば、Vue コンポーネントは Web Component の詳細な実装を知らないので、メタデータで表現されるインターフェース (つまり Web Component のインターフェース) が変わらない限りは自由に変更ができます。 また、アイコンデータの元になるリソースがFigma から別のサービスに変わったり、取得方法が変わったとしてもアイコンコンポーネントの生成に直接は影響を及ぼしません。
これは、方針の中で考えた『Web フロントエンド開発の基盤となりうるため変更しやすい作りにする』という点を満たすための重要な特徴です。
このようなアプローチは、抽象的なものに依存をさせて具体的な部分の変更を容易にするというソフトウェア実装の中でもよく用いられるものです。
一方で、ここで依存しているものたちが利用できなくなった場合 (例えば Web Component が使えなくなるなど)は非常に広範囲に対して影響が発生し、長期にわたって開発が停滞することが予想されます。 しかしながら、そのようなリスクはとても低いだろうと判断しています。 これは、依存している対象が非常に単純で必要なら自身で実装できるものであったり、互換性を非常に重視されている Web の標準的な技術であったりするためです。
また、抽象表現から最終的なライブラリは何かしらの方法で生成することを基本としています。これは、デザインシステムの変更に対して可能な限り早く追従できるようにしたいという点に合致したものになっています。
5. おわりに
この記事ではまず、アンドパッドのデザインシステム『Tsukuri』の Web 向け実装である、『Tsukuri for Web』の開発に至るまでの背景を紹介しました。 次に、それを踏まえての方針とその理由を説明し、最後にその方針を実現するための全体像について紹介しました。
ここで紹介した方針に対してどのようなツールやライブラリを利用して開発をしているかなど、より実装や開発に近い内容を別の記事で紹介したいと思います。
デザインシステムという概念が広く知られたのとともに、Web フロントエンドの開発をサポートするツールやライブラリが充実してきたことで様々な方法でデザインシステムとそれの Web 向け実装が開発されていると思います。 この記事が、これからデザインシステムの Web 向け実装を開発しようとしている方や、既に開発をしている方にとって参考になるような情報が含まれていれば幸いです。
また、このような試みに興味を持った Web フロントエンド開発者や UI デザイナーの方がいらっしゃったらお気軽にご連絡をいただけると嬉しいです。
その他のポジションについては、下記サイトをご覧ください!
この記事の続編となる記事が公開されました。
より詳細な実装について書きましたので、合わせてお読みください。