Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OSSのUIライブラリでESLintのカスタムルールを作っている話

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for chida0909 chida0909
June 10, 2026
25

 OSSのUIライブラリでESLintのカスタムルールを作っている話

Avatar for chida0909

chida0909

June 10, 2026

Transcript

  1. © Findy Inc. TSKaigi Night talks ~after conference~/ 2026-06-10 OSS

    の UI ライブラリで ESLint のカスタムルールを 作っている話 ファインディ株式会社 千⽥ 孝明 1
  2. © Findy Inc. 2 ⾃⼰紹介 • 千⽥ 孝明(Takaaki Chida) •

    ファインディ株式会社 / Web エンジニア • Yamada UI のメンテナ • 1児の⽗
  3. © Findy Inc. 3 Yamada UI とは ⽇本発の React UI

    ライブラリ https://yamada-ui.com
  4. © Findy Inc. 4 課題 コンポーネントの誤選択 • 専⽤コンポーネントがあるのにも関わらず、 汎⽤コンポーネントを使⽤ props

    の誤った使い⽅ • デザイントークンを使わずハードコード • shorthand と longhand の混在 → 解決策: ESLint のカスタムルールを作成 Lint による検出と⾃動修正を可能にする
  5. © Findy Inc. 5 課題 コンポーネントの誤選択 • 専⽤コンポーネントがあるのにも関わらず、 汎⽤コンポーネントを使⽤ props

    の誤った使い⽅ • デザイントークンを使わずハードコード • shorthand と longhand の混在 → 解決策: ESLint のカスタムルールを作成 Lint による検出と⾃動修正を可能にする 今回はこちらについて
  6. © Findy Inc. 6 やりたいこと shorthand または longhand の統⼀について、ESLint で修正した時のイメージ

    shorthand <Box margin={4} /> // Fixed <Box m={4} /> longhand <Box m={4} /> // Fixed <Box margin={4} />
  7. © Findy Inc. 7 ESLint のカスタムルールを書く • ESLint の Rule.RuleModule

    を利⽤ • create メソッドにルールを定義 export const propsShorthand: Rule.RuleModule = { create(context) { return { // インポート文ごとに ImportDeclaration を呼ぶ ImportDeclaration(node) { }, // JSX ごとに JSXOpeningElement を呼ぶ JSXOpeningElement(node) { } } } } https://eslint.org/docs/latest/extend/custom-rules
  8. © Findy Inc. 8 仕組み • ESLint は書かれたコードを AST(抽象構⽂⽊)として認識 •

    AST explorer 等で ESLint がどう解析するかを⾒て実装する https://astexplorer.net/
  9. © Findy Inc. 9 実装で気を付けたこと(1) コンポーネントの参照元が Yamada UI か否かの判定 •

    props にルールを適⽤するために、そのコンポーネントが Yamada UI 固有のコン ポーネントか判定が必要 • Box という名前だけでは、他ライブラリ(Chakra UI, MUI 等)と区別できない • 出所はインポートにしか書かれていないため、インポート⽂を解析して判定しなけ ればならない // Box コンポーネントの重複例 import { Box } from "@yamada-ui/react" import { Box } from "@chakra-ui/react" import Box from "@mui/material/Box"; 名前の衝突が発⽣するため、 パッケージ名を確認する必要がある
  10. © Findy Inc. 10 実装で気を付けたこと(2) インポートの形式は様々あるため、それぞれ考慮が必要 named import { Box

    } from "@yamada-ui/react" <Box /> aliased import { Box as B } from "@yamada-ui/react" <B /> styled import { styled } from "@yamada-ui/react" <styled.div /> namespace import * as YUI from "@yamada-ui/react" <YUI.Box /> styled は HTML 要素を Yamada UI のスタイル機能付きコンポーネントに昇格させるファクトリのこと。 <styled.div /> の記法でスタイルをカスタマイズできる https://yamada-ui.com/ja/docs/components/styled
  11. © Findy Inc. 11 最終的な実装 1. インポート元を確認 対象パッケージ(@yamada-ui/react)からのインポートのみ追跡 2. コンポーネント

    / ネームスペースの分類 照合処理の仕⽅が変わるため 3. インポート元とコンポーネントを照合 • コンポーネントと⼀致するか → Box • ネームスペース(左端の)と⼀致するか → styled.div ⼀致すれば Yamada UI のコンポーネントと判定 → ルール適⽤
  12. © Findy Inc. 13 ルールを適⽤できないケース1 Yamada UI はコンポーネントを 2 つの⽅法で提供している

    • CLI からコンポーネントを追加した時、パスを任意で指定できる • デフォルトは @workspaces/ui だが、皆がデフォルトを使うとは限らない → 決まったパスを前提にインポート⽂を解析することができない https://yamada-ui.com/ja/docs/get-started/cli [1] モジュールからインポート @yamada-ui/react から直接読み込む [2] CLI でコードを追加 コンポーネントのソースコードをユーザー のリポジトリに追加
  13. © Findy Inc. 14 ルールを適⽤できないケース2 • 独⾃のコンポーネントに Yamada UI の

    style props を当てたいケース • この場合、コンポーネントは Yamada UI からインポートされたものではない → このケースでもインポート⽂の解析だけでは対応できない import { styled } from "@workspaces/ui" const StyledDiv = styled("div") export const CustomComponent = () => { return ( <StyledDiv p="4" bg="gray"> This is a custom component. </StyledDiv> ) } https://yamada-ui.com/ja/docs/components/styled 独⾃のコンポーネントの例 div に style props を当てた
  14. © Findy Inc. 15 型情報から判定する @typescript-eslint/parser で TypeScript Compiler API

    を使い、型を辿ってコン ポーネントの出所を特定する [1] シンボルを⾒る getSymbolAtLocation AST の識別⼦からシンボル を取得 シンボルによりインポート 元を辿れる [2] 型を辿る getTypeAtLocation コンポーネントの型を取得 し、props の型(BoxProps 等)や継承元を辿る 型をさらに追跡 [3] 宣⾔ファイルを特定 型を辿ると最終的に @yamada-ui/react に⾏き 着く Yamada UI と判定 https://typescript-eslint.io/packages/parser/
  15. © Findy Inc. 16 まとめ • コンポーネントを判定する仕組みを、作るのが予想以上に⼤変だった • AST explorer

    で構⽂⽊を⾒ながら⼿を動かしたことにより、 ESLint の仕組みが 分かるようになった • 今⽇の話で Yamada UI に少しでも興味を持っていただけたら、ぜひ触ってみて ください! 公式サイト: https://yamada-ui.com リポジトリ: https://github.com/yamada-ui/yamada-ui プルリクエスト: https://github.com/yamada-ui/yamada-ui/pull/7607