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

ZOZOTOWNフロントエンドにおけるディレクトリの分割戦略

 ZOZOTOWNフロントエンドにおけるディレクトリの分割戦略

2025/08/26 にクローズドで開催された「ちょっと株式会社 × 株式会社ZOZO 合同勉強会」で発表した登壇資料です。

株式会社ZOZO
ZOZOTOWN開発本部 ZOZOTOWN開発2部
WEBフロントエンドブロック
菊地 宏之

Avatar for ZOZO Developers

ZOZO Developers PRO

August 26, 2025
Tweet

More Decks by ZOZO Developers

Other Decks in Technology

Transcript

  1. © ZOZO, Inc. https://zozo.jp/ 3 • ファッションEC • 1,600以上のショップ、9,000以上のブランドの取り扱い •

    常時107万点以上の商品アイテム数と毎日平均2,700点以上の新着 商品を掲載(2025年6月末時点) • ブランド古着のファッションゾーン「ZOZOUSED」や コスメ専門モール「ZOZOCOSME」、シューズ専門ゾーン 「ZOZOSHOES」、ラグジュアリー&デザイナーズゾーン 「ZOZOVILLA」を展開 • 即日配送サービス • ギフトラッピングサービス • ツケ払い など
  2. © ZOZO, Inc. 7 避けたい課題 ❌ 迷子コンポーネント: 「なんとなくここに置いた」が蓄積してしまう ❌ 再利用できない:

    ページ固有の処理が混在してしまう ❌ 影響範囲が不明: どこで使われているか分からない ❌ チーム開発で混乱: メンバーごとに置き場所がバラバラになってしまう → これらを未然に防ぐ設計戦略が必要。
  3. © ZOZO, Inc. 8 解決アプローチ:責務分離パターン 役割を明確にした配置(責務分離)をすることになった。 1. コンポーネント層(src/components/) ◦ 役割別に5つのディレクトリに分類

    2. UIインフラ層(src/ui/) ◦ コンポーネントが利用する共通基盤 まずはコンポーネント層の設計や実装が始まり、実装していく中でUIインフラ層を作成。
  4. © ZOZO, Inc. 9 コンポーネント層とUIインフラ層の関係 Pages / Models Layouts /

    UI src/components/ ← ビジネスロジック src/ui/ themes / styled / constans ... ↓ 利用 ← レイアウト・UIパーツ ← 共通基盤・スタイル定義 ↓ 利用
  5. © ZOZO, Inc. 11 コンポーネント層の設計 src/components/ ├── UI/ ├── Models/

    ├── Pages/ ├── Layouts/ └── Functional/ 他社事例を参考に5つに分割したディレクトリ構成。 ディレクトリの命名については、Next.jsのルーティング用のディレクトリ(src/pages)と混同しやす く、内容としてもコンポーネントのためのディレクトリであることから頭を大文字としている。
  6. © ZOZO, Inc. 12 コンポーネント層の設計(分類) 責務ごとに分離している。 名前 役割 格納するコンポーネント例 UI

    機能を持たないUI Button, Collapse, Image... Models ドメインロジックがある ProductList, BrandList... Pages ページ専用 HomePage, SearchPage... Layouts アプリに関わるレイアウト Layout, Columns, Grid... Functional UIを持たず機能のみ Analytics, GlobalStore...
  7. © ZOZO, Inc. 13 コンポーネント作成時の判断フロー 1. 特定のページでのみ使用するコンポーネントか? → YES: src/components/Pages/

    ディレクトリに配置 2. アプリ全体のレイアウト構造に関わるか? → YES: src/components/Layouts/ ディレクトリに配置 3. 特定のドメインロジックを含み複数ページで使用するか? → YES: src/components/Models/ ディレクトリに配置 4. UIのみの汎用的なコンポーネントか? → YES: src/components/UI/ ディレクトリに配置 5. アプリケーションの機能的側面をサポートするか? → YES: src/components/Functional/ ディレクトリに配置
  8. © ZOZO, Inc. 14 実装例:依存関係の明確化 // UI/ProductCard - UIコンポーネント export

    const ProductCard = ({ name, price, image }) => ( <Card> <Image src={image} /> <Title>{name}</Title> <Price>{price}</Price> </Card> ) // Models/ProductList - ドメインロジック + UIを利用 export const ProductList = (props) => { const { products } = useProductData(props) return ( <Grid> {products?.map((product) => ( <ProductCard key={product.id} {...product} /> ))} </Grid> ) }
  9. © ZOZO, Inc. 15 品質担保 'strict-dependencies/strict-dependencies': [ 'error', [ //

    Pagesコンポーネントの依存ルール { module: 'src/components/Pages', allowReferenceFrom: ['src/pages'], allowSameModule: false, }, // Modelsコンポーネントの依存ルール { module: 'src/components/Models', allowReferenceFrom: ['src/components/Pages'], allowSameModule: true, }, // (省略)他のコンポーネントも同様に定義... eslint-plugin-strict-dependenciesを利用して、間違った依存関係を自動検出。依存関係のルールを矯正する。
  10. © ZOZO, Inc. 17 UIインフラ層の設計 src/ui/ ├── themes/ # 色・mixin・関数・ブランドテーマ定義

    │ ├── mixins/ # Mixin ヘルパー │ ├── functions/ # 関数ヘルパー │ └── themeVariants/ # ブランド別テーマ ├── styled/ # Emotion のスタイル関数群 ├── libs/ # UI ユーティリティ ├── constants/ # UI 共通定数 └── stylelint-plugins/ # カスタム Stylelint ルール UIに関連する処理や仕組みを共通で利用する基盤を管理。 変更の影響を局所化し、一貫性の確保が目的。
  11. © ZOZO, Inc. 18 統一されたスタイル定義 ZOZOTOWN では CSS in JS(Emotion)を採用している。

    Sass や PostCSS のように mixin や function を利用して、スタイルの再利用性を高めるアプローチを取っている。 const Button = styled.button` ${({ theme }) => theme.mixin.hoverOpacityEffect()}; ` const Label = styled.span` font-weight: ${({ theme }) => theme.function.fontWeight('bold')}; line-height: ${({ theme }) => theme.function.lineHeight(24, 16)}; ` コーディング規約も用意したり、Stylelintによる矯正も用意している。
  12. © ZOZO, Inc. 21 テーマシステム(ThemeProvider)の利用シーン②:サイトジャック ブランド出店の施策で「サイトジャック」と称して、ZOZOTOWNのカラーを期間限定でブランドカラー に置き換えることがある。 const JACK_COLOR =

    '#FF1493' // サイトジャックカラー export const siteJackTheme: ColorTheme = { header: { background: JACK_COLOR }, navigation: { border: JACK_COLOR }, button: { primary: { background: JACK_COLOR } }, // ... }
  13. © ZOZO, Inc. 23 品質担保 Stylelintのプラグインを継続的に自作して品質を担保している。 • Emotion(CSS in JS)利用時にハイドレーションエラーになりえる疑似クラス(:first-child

    等)の利用を警告するプラグイン NG: .item:first-child { margin-left: 0; } OK: .item:first-of-type { margin-left: 0; } • line-height 指定は px 単位なしを推奨するプラグイン NG: .item { line-height: 16px; } OK: .item { line-height: 1.6; }
  14. © ZOZO, Inc. 25 まとめ - ディレクトリの分割戦略 • 責務分離を意識したディレクトリ設計 ◦

    コンポーネント層(src/components/) ▪ 責務ごとに5つに分けて開発者が迷わない配置 ◦ UIインフラ層(src/ui/) ▪ スタイリングを始めとする UI に関連する処理や仕組みを集約して効率化 • 開発者が迷わない仕組み作り ◦ ESLint や Stylelint といったツールを活用して機械的にルールを矯正