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をします