ピクシブのデザインシステム「Charcoal」アイコンライブラリをつくる
by
mimo
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
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をします