N

Nokfa Docs

Current: framework-next.js

ไม่มีชื่อบทความ

โครงสร้างโฟลเดอร์ Monorepo ของ Nokfa

เอกสารนี้อธิบายภาพรวมโครงสร้าง Monorepo ของบริษัท Nokfa ประกอบด้วยโฟลเดอร์หลัก apps สำหรับแอปพลิเคชัน, packages สำหรับไลบรารีที่แชร์, และ config สำหรับการตั้งค่ากลางต่างๆ


1. ภาพรวมโครงสร้าง (ASCII Diagram)

/
├── apps/
│   ├── web/
│   │   ├── app/
│   │   │   ├── page.tsx
│   │   │   └── layout.tsx
│   │   ├── public/
│   │   ├── next.config.js
│   │   └── package.json
│   └── admin-dashboard/
│       ├── app/
│       │   ├── page.tsx
│       │   └── layout.tsx
│       ├── public/
│       ├── next.config.js
│       └── package.json
│
├── packages/
│   ├── ui/
│   │   ├── src/
│   │   │   ├── Button.tsx
│   │   │   └── Card.tsx
│   │   ├── package.json
│   │   └── tsconfig.json
│   ├── utils/
│   │   ├── src/
│   │   │   ├── date.ts
│   │   │   └── fetcher.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   └── data-access/
│       ├── src/
│       │   ├── firestore.ts
│       │   └── auth.ts
│       ├── package.json
│       └── tsconfig.json
│
├── config/
│   ├── eslint/
│   │   └── .eslintrc.js
│   ├── prettier/
│   │   └── .prettierrc.js
│   ├── tsconfig.base.json
│   └── turbo.json
│
├── package.json
├── pnpm-workspace.yaml
└── README.md

2. โฟลเดอร์ apps/

  • วัตถุประสงค์: เก็บแอปพลิเคชันจริงที่ deploy ไปยัง Vercel

  • แต่ละโฟลเดอร์ภายใน apps เป็น Next.js App Router instance

  • โครงสร้างภายในแต่ละแอป:

    • app/ – โค้ดหน้าตา UI, routes, layouts
    • public/ – static assets (ภาพ, favicon)
    • next.config.js – ปรับตั้งค่า Next.js เฉพาะแอป
    • package.json – dependency เฉพาะแอป, สคริปต์
  • ตัวอย่าง:

    • apps/web – เว็บไซต์หน้า Public (marketing)
    • apps/admin-dashboard – ระบบหลังบ้าน (จัดการข้อมูล, dashboard)

3. โฟลเดอร์ packages/

  • วัตถุประสงค์: ไลบรารีที่แชร์ข้ามหลายแอป เพื่อหลีกเลี่ยงโค้ดซ้ำ

  • แต่ละโฟลเดอร์ภายใน packages เป็น npm package เล็กๆ

  • โครงสร้างภายใน:

    • src/ – โค้ด TypeScript หรือ React component
    • package.json – ชื่อแพ็กเกจ, version, dependencies
    • tsconfig.json – config TS เฉพาะแพ็กเกจ (extends จาก base)
  • ตัวอย่างแพ็กเกจหลัก:

    1. ui

      • ปุ่ม, การ์ด, modal, theme utilities
      • ใช้ร่วมระหว่าง web และ admin-dashboard
    2. utils

      • ฟังก์ชันช่วยเรื่องวันที่, fetch wrapper, error handler
    3. data-access

      • wrappers สำหรับ Firestore, Firebase Auth, server actions

4. โฟลเดอร์ config/

  • วัตถุประสงค์: เก็บการตั้งค่ากลางให้ทุกแพ็กเกจและแอปใช้ร่วมกัน

  • รายการไฟล์หลัก:

    • eslint/.eslintrc.js

      • config rule, plugin, shared globals
    • prettier/.prettierrc.js

      • format style: semi, singleQuote, printWidth
    • tsconfig.base.json

      • compilerOptions กลาง: paths, strict, target
    • turbo.json

      • กำหนด pipeline tasks, cache strategy, output directories
  • pnpm-workspace.yaml (ระดับ root)

    packages:
      - 'apps/*'
      - 'packages/*'
      - 'config'
    
  • package.json (ระดับ root)

    • สคริปต์ทั่วไป:

      {
        "scripts": {
          "dev": "turbo run dev",
          "build": "turbo run build",
          "lint": "turbo run lint",
          "test": "turbo run test"
        }
      }
      

5. การตั้งค่า TurboRepo ( turbo.json )

{
  "$schema": "https://turborepo.org/schema.json",
  "pipeline": {
    "dev": {
      "cache": false
    },
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"]
    },
    "lint": {
      "outputs": []
    },
    "test": {
      "outputs": []
    }
  }
}
  • dev – สั่งรัน local server ทุกรายการ (apps/*)
  • build – build เรียงลำดับตาม dependency graph
  • lint – ตรวจโค้ดแบบ static analysis
  • test – รัน unit/integration tests

6. ตัวอย่างคำสั่ง CLI

# ติดตั้ง dependencies ทั้งหมด
$ pnpm install

# รันทุกแอปในโหมด dev
$ pnpm dev

# สั่งรัน dev สำหรับแอปเฉพาะ
$ pnpm --filter web dev
$ pnpm --filter admin-dashboard dev

# Build production ทั้งหมด
$ pnpm build

# ตรวจ lint ทุกแพ็กเกจและแอป
$ pnpm lint

# รัน test ในโฟลเดอร์ utils เท่านั้น
$ pnpm --filter utils test

7. ตัวอย่าง Import ข้ามแพ็กเกจ (Cross-package)

  • ตั้งค่า alias ใน tsconfig.base.json

    {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@nokfa/ui": ["packages/ui/src"],
          "@nokfa/utils": ["packages/utils/src"],
          "@nokfa/data-access": ["packages/data-access/src"]
        }
      }
    }
    
  • ใน apps/web/app/page.tsx

    import { Button } from '@nokfa/ui';
    import { formatDate } from '@nokfa/utils';
    import { getUser } from '@nokfa/data-access';
    
    export default function HomePage() {
      const today = formatDate(new Date());
      const user = await getUser();
      return (
        <main>
          <h1>สวัสดี, {user.name}</h1>
          <p>วันนี้วันที่ {today}</p>
          <Button onClick={() => console.log('clicked')}>Click me</Button>
        </main>
      );
    }
    

8. Best Practices & ข้อแนะนำ

  • แยกความรับผิดชอบชัดเจน:

    • apps/ = deployable applications
    • packages/ = reusable libraries
    • config/ = global config
  • ใช้ alias & shared tsconfig เพื่อความสะดวกในการ import

  • รักษา version ในแต่ละ package.json อย่างสม่ำเสมอ

  • CI/CD: ตั้ง pipeline ให้แยก lint/test/build per scope และ cache ผลลัพธ์

  • Document: อัปเดต README.md ในแต่ละโฟลเดอร์อธิบายวิธีเริ่มต้นใช้งาน


หมายเหตุ: โครงสร้างนี้ปรับแต่งเพิ่มเติมได้ตามขนาดทีมและความซับซ้อนของโปรเจกต์ แต่สำหรับทีม Nokfa ขนาด 2 คน Monorepo ช่วยให้ Dev ใหม่เข้ามาทำงานได้เร็ว ปรับแก้โค้ดร่วมกันง่าย และจัดการ CI/CD รวมศูนย์ได้ตรงตามเป้าหมาย