ピクシブのデザインシステム「Charcoal」アイコンライブラリをつくる
by
mimo
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
pixiv.inc ピクシブのデザインシステム「Charcoal」 アイコンライブラリを つくる @mi2_okmt
Slide 2
Slide 2 text
Profile mimo フロントエンドエンジニア 2022年 新卒入社 CTO室デザインシステム部 兼 クリエイター事業部 FACTORY部 初音ミクが好き DJする趣味がある
Slide 3
Slide 3 text
しゃべること ● Charcoalとは? ● charcoal-ui/iconsとは? ● charcoal-ui/iconsをつくる ● SVGのimportについて
Slide 4
Slide 4 text
とは?
Slide 5
Slide 5 text
とは? ● pixivをはじめ、様々なプロダクトが利用 ● web / iOS / Android それぞれに対応した実装がある ● 2022年7月からはデザインシステム部が開発してる ○ DEV MEETUP(2020) のときはタスクフォースだった ○ 部外からもドカドカPRをくれるのでレビューしてる ピクシブのデザインシステム「Charcoal」
Slide 6
Slide 6 text
● 10個のパッケージを持つweb実装のモノレポ ● @charcoal-ui/styled, /tailwind-config, /react …などなど ● 今回は @charcoal-ui/icons について話します web実装 pixiv/charcoal とは?
Slide 7
Slide 7 text
@charcoal-ui/icons
Slide 8
Slide 8 text
@charcoal-ui/icons ● Web Componentsとして実装 ○ 他フレームワークへの依存なしで利用可能 ○ Charcoalの他パッケージへの依存もほとんどない ● SVGファイルを独自アイコンとして登録できる Charcoalのアイコンライブラリ
Slide 9
Slide 9 text
@charcoal-ui/icons 1. yarn add @charcoal-ui/icons 2. import ‘@charcoal-ui/icons’ 3. 簡単 3ステップ クイックスタート!
Slide 10
Slide 10 text
@charcoal-ui/icons パッケージの構造 Figma SVG stringをexportする JSのパッケージ @charcoal-ui/icon-files .cjs SVGを Custom Elementsにする @charcoal-ui/icons jsでimport @charcoal-ui /icons-cli
Slide 11
Slide 11 text
@charcoal-ui/icons ● Figma APIからSVGとしてアイコンを取得 ● fill属性を currentcolor に置き換える ● SVGをstringでexportするファイルをつくる ● /icon-files に差分があれば commit して PR をつくる Figmaのアイコンを取ってくる icons-cli
Slide 12
Slide 12 text
@charcoal-ui/icons ● icons-cli によって作られる.cjsファイルのパッケージ ● export default '
Slide 13
Slide 13 text
@charcoal-ui/icons ● icon-filesに依存 SVG文字列をCustom Elementsにする ● 指定されたSVGファイルをアイコンにする ○ icon-files にないアイコンを使いたい需要に対応 ○ PixivIcon.extend() Custom Elementsをつくる icons
Slide 14
Slide 14 text
どうして Web Components?
Slide 15
Slide 15 text
どうしてWeb Components? ● 2021年2月としては珍しい技術選択 ● ピクシブに求められる要件がいくつかあった @charcoal-ui/iconsはWeb Components
Slide 16
Slide 16 text
どうしてWeb Components? ● プロダクトごとに異なるフレームワーク ○ Smarty ERB React Vue … ● 導入がスムーズに行えること ● SSRできる ● 検討したがボツになったものを具体的に紹介します ピクシブでの要件
Slide 17
Slide 17 text
@charcoal-ui/icons ボツ案
Slide 18
Slide 18 text
@charcoal-ui/icons ボツ案 1. Reactでつくる 2. icon font 3. SVGR ボツ案一覧 4. SVGのuseタグ 5. Lit HTML
Slide 19
Slide 19 text
@charcoal-ui/icons ボツ案 × Reactでしか使えない ピクシブにはVueプロダクトもある (BOOTH pixivのSP版 …など) × ReactプロダクトでもReactだけを使うとは限らない 局所的にSmartyやERBをなこともある 1. Reactでつくる
Slide 20
Slide 20 text
@charcoal-ui/icons ボツ案 × フォントをつくるのがめんどくさい × font familyの上書きで変な文字が出る × スクリーンリーダーやa11yに弱い
タグなどを本来と異なる用途で使うため 2. icon font
Slide 21
Slide 21 text
@charcoal-ui/icons ボツ案 SVGR: SVGをimportするとReactコンポーネントになるもの × inline SVGになって、HTMLが巨大になるおそれ JSXからのimportでHTMLが巨大になるリスクが指摘されていた × React前提になる 3. SVGRのようなアプローチ
Slide 22
Slide 22 text
@charcoal-ui/icons ボツ案 id のついているSVG要素を useタグで呼び出せる × どうやってアイコンファイルを配信するか不明 SVGアイコン全部入りファイルを読み込ませる必要がありそう × ロード時間や維持管理が厳しそう 4. SVGのuseタグ
Slide 23
Slide 23 text
@charcoal-ui/icons ボツ案 Web Componentsが作れる薄めなライブラリ ✓ いったん採用した × SSR対応のとき、Lit HTMLが嫌な実装だったので結局やめた 5. Lit HTML
Slide 24
Slide 24 text
@charcoal-ui/icons ボツ案 × 内部でDOM APIをめっちゃさわる × SSRができない nodeでimportするとクラッシュした × lit-labs/ssr があったが嫌な実装だった globalThisにDOM APIを生やすような感じ ここがいい感じだったら採用していたかもしれない... 5. Lit HTML
Slide 25
Slide 25 text
そして Web Components へ
Slide 26
Slide 26 text
そして Web Components へ ✓ 使うアイコンだけ読み込ませられる ✓ 特定のフレームワークに依存させることなく実装できる ✓ 無理のない実装方法である ion-icon も Web Componentsだった SVGファイルをDOMにレンダリング
Slide 27
Slide 27 text
そして Web Components へ ● 当時「Vue 3でWeb Components対応」と言われていた ● SSR対応のCustom Elementsの参考に実装 ● globalThis に頼った箇所がひとつだけ残った ○ HTMLElementsがSSRでundefinedになるのを回避させる部分 SSRでも動くコードで実装
Slide 28
Slide 28 text
できあがった @charcoal-ui/icons
Slide 29
Slide 29 text
できあがった @charcoal-ui/icons 👍 dependenciesがたった2つになった DOMPurifyとwarningsのみ 👍 最新でも、レガシーでも、CSRでも、SSRでも使える tailwindもstyledもReactもVueもいらない! 👍 社内プロダクトへの導入がスムーズだった 良かったこと
Slide 30
Slide 30 text
できあがった @charcoal-ui/icons 🥳< 属人化していて更新しづらくて不幸になってました。 ツールでサポートされたので属人性も手間もなくなり、 工数削減だけでなく参入もしやすくなりました。 喜びの声
Slide 31
Slide 31 text
🤔 PixivIcon.extends() を使うときはバンドラの設定が必要 独自アイコンを使うなら各自でバンドラを設定してね! 🤔 a11yが不十分 もし対応不可能なことがあるとマズい 🤔 レイアウトシフトが起こりやすい ドキュメントにリセットCSSを載せてるだけなのでパッケージに含めたい... 残された課題・デメリット できあがった @charcoal-ui/icons
Slide 32
Slide 32 text
SVGのimport
Slide 33
Slide 33 text
SVGのimport おさらい Figma SVG stringをexportする JSのパッケージ @charcoal-ui/icon-files .cjs SVGを Custom Elementsにする @charcoal-ui/icons jsでimport @charcoal-ui /icons-cli
Slide 34
Slide 34 text
SVGのimport おさらい Figma SVG stringをexport するJSのパッケージ @charcoal-ui/icon-files .cjs SVGを Custom Elementsにする @charcoal-ui/icons jsでimport @charcoal-ui /icons-cli
Slide 35
Slide 35 text
SVGのimport ● 最近はwebpack以外のバンドラが増えた ○ vite swc Parcel … ● /icons は webpack 環境下でしか動かなかった ● 社内から webpack 以外でも動いてほしいとの要望が来た webpackが必須だった /icons v1.x.x
Slide 36
Slide 36 text
SVGのimport ● 「.jsではないものを相対パスで読み込む」に差が出やすい なぜ webpack でしか動かなかったのか const { default: filepath } = await import( `../svg/${encodeURIComponent(size)}/ ${encodeURIComponent(name)}.svg` ) ● jsに従って文字列を扱えば解決するのでは?
Slide 37
Slide 37 text
SVGのimport ● CIでやることを追加 ○ icons-cli で SVGを取ってきてSVGファイルをつくる ○ + SVGファイル → string を export する .cjs ファイル ○ + 保存する場所を /icon-files に変更 ○ つくったファイルをまとめてcommit v2.x.x から増えた /icon-files
Slide 38
Slide 38 text
SVGのimport ● アイコンの import する処理を分離 ○ SVG string 用の関数を用意 ○ 独自アイコン用に dynamic import する処理も残す ■ PixivIcon.extends()にバンドラ設定が必要なのはこのため /icons の SVG import 改修
Slide 39
Slide 39 text
SVGのimport // v1.x.x const { default: filepath } = await import( `../svg/${encodeURIComponent(size)}/ ${encodeURIComponent(name)}.svg` ) // v2.x.x import charcoalIconFiles from ‘@charcoal-ui/icon-files’ get importIconFile() { return charcoalIconFiles[this._name] }
Slide 40
Slide 40 text
今後の話
Slide 41
Slide 41 text
今後の話 ● webpack以外でも使えることを確認すべき ● 依存ライブラリのバージョンアップの影響もうける ○ /icons だけは依存ライブラリの影響は少ない ○ 他パッケージは peer dependenciesが多い ■ /react /tailwind-config /styled … 動作環境、依存ライブラリはどんどん変わる
Slide 42
Slide 42 text
今後の話 ● /icons は a11y やパフォーマンスの課題を抱えている ● Charcoalは品質をあげるステップに入った ○ より安定、よりハイパフォーマンスであるべき ● Charcoalのぜんぶで頑張っている最中 ● キリがないのであとでとっ捕まえて聞いてください デザイナーやiOSエンジニアも捕えておきます
Slide 43
Slide 43 text
宣伝 ● Charcoalのセッションは他にもあります! ○ SUB STAGE: cilvia「BOOTHにおけるCharcoal実践活用術」 現場で実際に行われているテーマのカスタムなどの話が聞けそうです ○ SUB STAGE: ああうえ「Charcoalをモバイルアプリで使う」 CharcoalのiOS開発メンバーの発表です ● 懇親会パートでmimoはDJをします