SODA Engineering Blog
📝

FEチームでReactのリアーキテクチャを行おうとしています!

2024/05/31に公開

こんにちは。FEチームのMapleです。私たちのチームは、現在のシステムアーキテクチャを見直し、Reactを用いた新しいアーキテクチャへの移行を検討しています。このブログでは、その背景や目的、現状の課題、そして今後の方針について共有します。

目的

新しいアーキテクチャの目標

  • 複数のチームが効率的に分担して開発できるシステムを構築
  • それぞれのStream-aligned teamが、同じくらいの認知負荷で仕事目線のValue streamを流せるようにする

現状の課題

コンポーネントの分割

  • 現在のシステムでは、適切にコンポーネントが分かれておらず、作業を進める中で分ける必要があります。また、VueではdefinePropsやdefineEmitsなど、分けられない箇所があり、認知負荷が高い

ロジック分割のルールの不統一

  • 現状、ロジックの分割方法に統一されたルールがなく、各開発者が独自の方法で実装しているため、コードの可読性や保守性が低下している

子コンポーネントのタスク分割

  • 現状、子コンポーネントごとにタスクを切り出し、最後に親コンポーネントにマウントする方法を採用していますが、これも一貫性が欠けており、改善が必要

新機能追加の難しさ

  • 新しい機能やページを追加する際、現状の正解の書き方が分からず、開発がスムーズに進まないことが多いです。また、optionsAPIとCompositionAPIの書き方が混在しており、影響範囲の特定が困難です。

CI/CDの遅延

  • バックエンドの変更がなくてもCIを実行しなければならず、開発速度が遅くなっています。
  • テンプレート部分の改修後のビルド時間も長く、ブランチの切り替え時にはコンテナの再起動が必要になることもあります。

今後の方針

FEサーバーの分離

  • フロントエンドとバックエンドを分離し、CI/CDの効率を上げます。
  • フロントエンドの変更がバックエンドに影響を与えないようにします。

VueからReactへの移行

  • VueからReactへの完全移行を目指します。
  • Vueの現在の問題点(definePropsやdefineEmitsの制約、影響範囲の特定の困難さ、optionsAPIとCompositionAPIの混在)を解消するためです。

新しいReactアーキテクチャの採用

  • Reactのアーキテクチャとして、以下の構造を採用します。
public/  // 静的ファイル(画像、スタイルシート等)
src/
    lib/  // ライブラリをアプリケーション用に設定して再度エクスポートしたもの
        axios/
            index.ts
        react/
            image.tsx
            index.ts
        ライブラリ名/
            hogehoge.ts
            __test__/
                hogehoge.test.ts
            index.ts  // 必ず置く
        index.ts  // 必ず置く
    api/  // 共有 API リクエスト関数の配置場所
        accounts/  // ドメイン名
            useHogeFuge.ts  // ドメイン名以下のエンドポイント
            index.ts  // exportするだけのファイル
            __test__/
                useHogeFuga.test.ts  // テストファイル
    config/  // 環境変数をまとめる
    common/  // 共有コンポーネントやユーティリティ・フック
        __tests__/  // テストファイル
        components/
            atoms/
                button/
                input/
                logo/
                numbers/
            molecules/
                InputSearchBox/
                    Input.tsx
                    Suggest.tsx
                    InputSearchBox.tsx  // または index.tsx
                    hooks.ts
                nav/
                index.ts
            organisms/
                header/
            templates/
            pages/
        hooks/
            useHogeHoge/
                index.ts
        stores/
            global.ts
            top.ts
            globalStoreProvider/
                login/
            topPageProvider.tsx
            apparelStoreProvider/
                apiで撮ってきた値
            sneakerStoreProvider/
                apiで撮ってきた値
            piyoStoreProvider/
                apiで撮ってきた値
        types/  // 共有の TypeScript 型
        index.ts  // 共有のエントリーポイント(公開 API)
    features/  // 機能ごとのディレクトリ
        Feature1/  // 'Feature1' という名前の機能
            __tests__/  // テストファイル
            components/
                atoms/
                molecules/
                organisms/
                templates/
                pages/
            hooks/  // Feature1 固有のフック
            stores/  // Feature1 固有の状態ストア
                再描画防止用store
                propsバケツリレー防止ストア
            types/  // Feature1 固有の TypeScript 型
            index.ts  // Feature1 のエントリーポイント(公開 API)
    providers/  // 全体プロバイダー
    app/  // App Routerのディレクトリ
        store.ts
        provider.tsx
            const Provider = () => (
                <ApparelProvider store={apparel}>
                    <SneakerProvider>
                        <OfferProvider>
                            {children}
                        </OfferProvider>
                    </SneakerProvider>
                </ApparelProvider>
            )
    stores/  // 全体または複数機能間で共有される状態ストア
    mocks/  // モックサーバー
    types/  // 全体で使用される基本 TypeScript 型
.env
.env.local
.env.production
.env.development

まとめ

私たちのチームは、Reactを用いた新しいアーキテクチャを導入することで、開発効率の向上と認知負荷の軽減を目指しています。 ご興味あるかは是非コメントやFEへご応募下さい^^

SODA Engineering Blog
SODA Engineering Blog

Discussion