2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
リンクをコピー
記事をブックマーク
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.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2024.11.29
「明日までにお願いできますか?」ちょっとカチンとくる一言 頭がいい人に見える上品な言い方に変えるコツ
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.04
いつも遅刻や自慢話…自分勝手な人にイラっとした時の切り返し 不平等な関係を打開する「相手の期待」を裏切る技
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.03
職場の同僚にイライラ…ストレスを最小限に抑える方法 臨床心理士が語る、「いい人でいなきゃ」と自分を追い込むタイプへの処方箋
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
2024.12.05
「今日こそやろう」と決めたのに…自己嫌悪でイライラする日々を変えるには
PR | 2024.12.04
攻撃者はVPNを狙っている ゼロトラストならランサムウェア攻撃を防げる理由と仕組み