2024.10.01
自社の社内情報を未来の“ゴミ”にしないための備え 「情報量が多すぎる」時代がもたらす課題とは?
リンクをコピー
記事をブックマーク
mimo氏:こんにちは。これから、「ピクシブのデザインシステム『Charcoal』アイコンライブラリをつくる」のセッションを始めていきます。
まず自己紹介からさせてください。自分は、mimoと申します。2022年に新卒入社して、デザインシステム部と、オンデマンド印刷サービスを開発しているFACTORY部を兼務しています。
趣味的なことを言うと、初音ミクが大好きです。あとはDJをする趣味があって、最近は「RubyKaigi」に絡めたDJイベントをしたりしています。
自分のセッションでは、(スライドを示して)この4つに大きく分けて話していきます。まず、「Charcoalとは?」と題して、Charcoalデザインシステムそのものについて紹介をします。
その次に、「@charcoal-ui/iconsとは?」と題して、CharcoalのWeb実装は、実はパッケージが10個あるモノレポになっているのですが、その中の「icons」というライブラリについて紹介します。
3番目に、「@charcoal-ui/iconsをつくる」と題して、@charcoal-ui/iconsのアーキテクチャや実装の話に触れていきます。そして最後に、アイコンライブラリの一番のミソであるSVGのimportについて内部の実装がどうなっているかを紹介していきます。
ではまず、ピクシブのデザインシステム、Charcoalをご紹介します。
Charcoalは、ピクシブのデザインシステムです。SNSの「pixiv」をはじめ、「BOOTH」「pixivFACTORY」「VRoid Hub」などのプロダクトで全社的に利用されています。
CharcoalはWeb実装だけでなく、iOSの実装、Androidの実装も存在しており、そのすべてがOSSとして公開されています。また、Charcoalは2020年に「PIXIV DEV MEETUP」でOSS化しますとお披露目されました。このようなカンファレンスに来ていただいている方は、記憶に新しいかと思います。
そこから2年が経ち、当時はタスクフォースとして、部署とはなっていなかったのですが、2022年、Charcoalをメンテナンスする部署として、デザインシステム部というものが新しく立ち上がりました。今、そのデザインシステム部のメンバーが日夜開発を続けています。
デザインシステム部は、基本的にほかのプロダクトと兼務しているメンバーが所属していて、中にはUIデザイナー、Webフロントエンドエンジニア、モバイルアプリエンジニアなどが在籍しています。
それから、部外からもドカドカと、プルリクエストをいただいているので、それをレビューしたりマージしたりリリースしたりというのも自分たちのお仕事です。
今回お話しする、アイコンライブラリが含まれるCharcoalのWeb実装についても詳しく紹介します。先ほども申し上げたのですが、CharcoalのWeb実装が入っている、pixiv/charcoal.gitというリポジトリは、10個のパッケージを持っている、Web実装のモノレポになっています。
例えば、「@charcoal-ui/styled」「@charcoal-ui/tailwind-config」「@charcoal-ui/react」など、それぞれのフレームワークに対応したライブラリが、このモノレポの中には含まれています。今回はその中でも、アイコンライブラリである@charcoal-ui/iconsについてお話をしていきます。
@charcoal-ui/iconsには、アイコンが150種類以上収録されています。使い始めれば、これらのアイコンがいくらでも使いたい放題という感じになっています。
@charcoal-ui/iconsは、Charcoalのアイコンライブラリとして存在していて、Web Componentsとして実装されています。Web Componentsは、再利用できるHTML要素を作る方法として標準化されているもので、特定のフレームワークやライブラリに依存する必要がありません。
その特徴を活かして、@charcoal-ui/iconsは「styled-components」などのフレームワークに依存することなく使えるように作られています。
Charcoalモノレポ内の、ほかのパッケージへの依存もほとんどないので、簡単に使い始めることができます。また、@charcoal-ui/iconsに収録されていないアイコンを使いたい場合にも対応できるよう、SVGファイルを独自アイコンとして登録できるAPIも提供しています。
ピクシブにはさまざまなサービスがあり、それらのロゴや独自機能のアイコンなどがよく作られるので、この機能を使って対応をお願いしています。
@charcoal-ui/iconsは、簡単に使い始められると先ほど言ったのですが、どれぐらい簡単に使えるのか、3行にまとめてきました。
yarn addして、importして、pixiv-iconというタグを書く、これだけで使えるので、みなさんもおうちに帰ったらぜひ使ってみてください。
続いて、@charcoal-ui/iconsのパッケージ構造も簡単に説明します。@charcoal-ui/iconsをアイコンライブラリたらしめる役者としては、「Figma」のアイコンがまとまっているファイルと、「icons-cli」「icon-files」というパッケージがあります。
デザイナーは、Figmaにアイコンを追加したり編集したりしています。@charcoal-ui/icons-cliは、週1回「GitHub Actions」でFigmaのAPIを使って、Figmaのファイルの中からアイコンのSVGデータをたくさん取ってきて、icon-filesの中にファイルを作っています。
icon-filesはSVGのタグを文字列としてたくさん持っていて、それをexportするだけのJavaScriptのファイルがたくさんあります。
@charcoal-ui/iconsは、icon-filesのSVGタグの文字列がexportされているJavaScriptのファイルをimportしてきて、それをWeb ComponentsのCustom Elementsとして登録する機能を持っているというアーキテクチャになっています。
それぞれのパッケージをもう少しだけ詳しく説明させてください。@charcoal-ui/icons-cliは、Figmaのアイコンを取ってきて、ファイルを作って、プルリクエストを作るところまでやっています。FigmaにはAPIがあり、それでファイルの中の特定のレイヤーのものを書き出してSVGを取得しています。
取得したSVGは、Figmaで塗り潰されてしまっているので、fill属性をcurrentcolorというものに置き換えます。これでWebで出した時にCSSで色が変えられるようになります。
SVGの下処理ができたら、そのSVGを文字列としてexportするだけのJavaScriptのファイルを作って、置いています。ファイルを作った結果、icon-files配下に差分があれば、プルリクエストを作ってエンジニアにレビューをしてもらって、マージをしてリリースするというワークフローになっています。
続いて、@charcoal-ui/icon-filesについてです。@charcoal-ui/icon-filesは、SVGタグを文字列としてexportするJavaScriptのファイルをいっぱい持っているパッケージです。
そのコードはほとんどが「export default '<svg……」うんたらかんたらという、(スライドを示して)こんな感じのコードが1行だけ存在するファイルになっていて、本当にこれだけの単純なパッケージです。
実は2022年にバージョン2にアップデートする時にけっこう仕組みを変えていて、このパッケージはその時に新しく追加したものです。どうしてこういうパッケージを作るに至ったのかは、後ほど説明しますのでお楽しみに。
最後に、@charcoal-ui/iconsです。@charcoal-ui/iconsは、先ほどのicon-filesに依存しています。icon-filesのSVG文字列をCustom Elementsとして登録する機能を持っていて、指定されたSVGファイルを登録する機能も提供しています。
icon-filesにないアイコンを使いたい時には、この指定されたSVGファイルを登録する機能を使ってなんとかしてくださいということになっています。
次に、なぜ@charcoal-ui/iconsは、Web Componentsになることを選んだのかについて説明します。
アイコンライブラリというと、例えば「Font Awesome」みたいにアイコンフォントにしたり、「React Icons」みたいにReactコンポーネントで作ってしまえばいいのでは、と思うかもしれません。しかし、iconsに求められていた要件と、紆余曲折あった技術選択があるので、それについて紹介していきます。
あらためて、@charcoal-ui/iconsは、Web Componentsとして作られています。npmパッケージとしてのCharcoalの開発は、2021年頃から始まっていて、その当時としては少々珍しい技術選択だったそうです。
Web Componentsは、ECMAScript 2015で標準化された機能で、2016年から「Chrome」と「Safari」で、2018年から「Firefox」で、2020年からやっと当時の「Edge」で使えるようになったようなので、確かにギリギリな感じがします。
それでもWeb Componentsが最適な手段のように思えたのは、ピクシブとして求められることがあったためでした。アイコンライブラリを作る上で課題になったのは、(スライドを示して)このようなことでした。
一番の課題は、ピクシブの展開するサービスごとに使っているフレームワークが異なること。PHPのテンプレートエンジンの「Smarty」が使われている部分もあるし、Railsプロダクトになれば、ERBやSlimを使っている部分もあります。
Reactが採用されていたとしても、全部がReactというわけでもなく、奥底までたどっていくとSmartyがいたり、管理画面はバリバリ、テンプレートエンジンだったり、Reactだけでなく、ピクシブにはVueを使っているプロダクトもいくつかあります。
これらに対応できないと、そもそも導入が不可能に近くなってしまうため、対応する必要があります。また、スムーズに導入でき、アイコンの更新に手間がかからないこと、SSRにも対応できることも要件に加えました。これらの要件を念頭に検討したものの、採用に至らなかったものが5つほどあるので、それらについて紹介します。
ということで、@charcoal-ui/iconsボツ案と題して、5つほど紹介していきます。ボツになったものが、(スライドを示して)この5つです。けっこうみなさんも使っているものがあると思うのですが、順番に話していきます。
まず、Reactでアイコンライブラリを作ることです。これは、アイコンライブラリを使うためにReactを導入する必要が生まれてしまうためボツとなりました。
「Reactプロダクトだけでも対応できればそれでいいじゃん」と思うかもしれませんが、先ほどもちょっと言ったように、Reactを採用しているプロダクトだとしても、古い画面はSmartyであったり、管理画面はERBを使っていたり、テンプレートエンジンを使っている部分があるので、「これがベストな手法である」とは言えないでしょう。
2番目のボツ案は、icon fontです。これは、Figmaから取ってきたSVGファイルをフォントにするのがちょっと難しそうというか、どうやってやったらいいのかが正直よくわからないというのが欠点になると思います。
この話題を話すにあたって、アイコンファイルをGitHub Actionsでいい感じに作るというのをちょっと調べたのですが、あまり知見がなさそうで、どうやったらいいかが正直よくわかりませんでした。
大変な思いをしてフォントファイルができてHTMLに読ませたとして、CSSでfont familyがもし上書きされたとしたら、結局変な文字が出る。
Font Awesomeなどを使っている人はよく経験があると思いますが、変な文字が出て、「なんだこの文字は?」となったり、うまくアイコンが入らないことが起こるのも考えられるし、スクリーンリーダーの対応やアクセシビリティのことを考えると、それにはすごく弱い方法なのかなと思い、ボツになりました。
次は、3番目のボツ案で、SVGRのような方法です。SVGRは、SVGをimportするとReactコンポーネントになるライブラリです。
SVGファイルをimportするだけなので簡単に見えると思いますが、JSXからSVGをimportすると、inline SVGになって、HTMLがすごく巨大になるおそれがあるのでやめようねという啓蒙がこの頃に行われていて、そうなってしまうとSSR対応が厳しくなりそうなので対応を見送りました。
また、JSXやReactであることが結局求められてしまうために、React前提になることから逃れられないと判断して、これは結局ボツになりました。
4番目のボツ案が、SVGのuseタグです。SVG内でid属性が付いているものを再利用するuseタグというものがあります。それを使ってアイコンをいい感じに出すのはどうかという案なのですが、useタグで呼び出すためにはそのsymbolを1つの巨大なSVGファイルにまとめなくてはならないという不安がありました。
それ以外も、「ファイルを細切れにしたとしても、どうやって読み込ませるねん?」というのがよくわかりませんでした。また、仮に1つの巨大なSVGファイルを作り出して、それを配信するとなれば、ページの読み込みが遅くなることと、アイコンの管理が難しくなることが予想されたため、これはボツとなりました。
最後に、「Lit HTML」の採用です。Lit HTMLは、Web Componentsが作れるライブラリです。
最近のVue 3などだと、Web Componentsとしても使える機能が提供されていたりするのですが、Vueほどコッテリしたライブラリは、この要件に対して必要ではないと感じていたため、Lit HTMLをいったん採用しました。
(スライドを示して)これが、昔のリポジトリを掘り返してきて発見した2年前ぐらいのコミットログなのですが、はっきりと「use lit-html」と書いてありますね。しかし、開発が進んでSSR対応を始めた時に、Lit HTMLのSSR対応のパッケージの実装がちょっと嫌な感じだぞということがわかってきたので、結局これはやめることになります。
Lit HTMLのそもそも何が嫌だったのかというポイントは、内部でDOM APIをたくさん触っていること。SSR対応がそのままだとできませんでした。
エクスペリメンタルなパッケージで、lit-labs/ssrだったかな、そんな感じのやつがあるのですが、これがエクスペリメンタルだったということもありました。
globalThisに対して、DOM APIのようなものをたくさん生やしているので、globalThisに、こんなもいっぱいいろいろなものを生やさなくても実装できるでしょう、と当時は考えていたので、これを採用しないことになりました。
ここの実装がglobalThisじゃなくいい感じになっていたら、もしかしたら最後までLit HTMLで作っていた可能性があります。
(次回へつづく)
関連タグ:
2024.10.29
5〜10万円の低単価案件の受注をやめたら労働生産性が劇的に向上 相見積もり案件には提案書を出さないことで見えた“意外な効果”
2024.10.24
パワポ資料の「手戻り」が多すぎる問題の解消法 資料作成のプロが語る、修正の無限ループから抜け出す4つのコツ
2024.10.28
スキル重視の採用を続けた結果、早期離職が増え社員が1人に… 下半期の退職者ゼロを達成した「関係の質」向上の取り組み
2024.10.22
気づかぬうちに評価を下げる「ダメな口癖」3選 デキる人はやっている、上司の指摘に対する上手な返し方
2024.10.24
リスクを取らない人が多い日本は、むしろ稼ぐチャンス? 日本のGDP4位転落の今、個人に必要なマインドとは
2024.10.23
「初任給40万円時代」が、比較的早いうちにやってくる? これから淘汰される会社・生き残る会社の分かれ目
2024.10.23
「どうしてもあなたから買いたい」と言われる営業になるには 『無敗営業』著者が教える、納得感を高める商談の進め方
2024.10.28
“力を抜くこと”がリーダーにとって重要な理由 「人間の達人」タモリさんから学んだ自然体の大切さ
2024.10.29
「テスラの何がすごいのか」がわからない学生たち 起業率2年連続日本一の大学で「Appleのフレームワーク」を教えるわけ
2024.10.30
職場にいる「困った部下」への対処法 上司・部下間で生まれる“常識のズレ”を解消するには