Skip to main content

Monorepo และสแตก

Alternun ใช้ monorepo แบบ pnpm workspace พร้อมการ orchestration ด้วย TurboRepo

การตัดสินใจนี้ตั้งใจไว้ชัดเจน เพราะรีโพนี้มีหลายแอปที่ใช้โครงสร้างพื้นฐาน รูปแบบการยืนยันตัวตน งานแปล primitive ด้านดีไซน์ และระบบอัตโนมัติของการออกรีลีสร่วมกัน

โครงสร้าง Workspace

พื้นผิวของแอป

apps/mobile

โค้ดเบสหลักของแอป AIRS

เทคโนโลยีหลัก:

  • Expo
  • Expo Router
  • React 19
  • React Native 0.81
  • React Native Web
  • Supabase JavaScript client
  • WalletConnect
  • Firebase
  • NativeWind และระบบสไตล์ที่ยึดแนวทาง Tailwind

ทำไมจึงสำคัญ:

  • โค้ดเบสเดียวรองรับทั้งรูปแบบเนทีฟบนมือถือและการส่งมอบบนเว็บ
  • ตระกูลโดเมนสาธารณะของ AIRS ถูกขับเคลื่อนจากแอปนี้ผ่านชั้นโครงสร้างพื้นฐาน

apps/admin

คอนโซลแอดมินภายใน

เทคโนโลยีหลัก:

  • Vite
  • React 18
  • React Router
  • Refine
  • oidc-client-ts

ทำไมจึงสำคัญ:

  • แยกเวิร์กโฟลว์ด้านปฏิบัติการออกจากประสบการณ์สาธารณะของ AIRS
  • สามารถปรับใช้ร่วมกับ API ใน dashboard stack ได้

apps/api

บริการแบ็กเอนด์แบบกำหนดเอง

เทคโนโลยีหลัก:

  • NestJS 10
  • Fastify 4
  • Swagger / OpenAPI
  • ตัวแปลงสำหรับ AWS Lambda

ทำไมจึงสำคัญ:

  • ทำให้แพลตฟอร์มมีที่สำหรับตรรกะแบ็กเอนด์เฉพาะที่ไม่ควรอยู่ในไคลเอนต์
  • ปัจจุบันมีทั้ง health endpoint และ flow เชิงการเชื่อมต่อ เช่น พฤติกรรม Decap OAuth bridge

apps/docs

เว็บไซต์เอกสารสาธารณะ

เทคโนโลยีหลัก:

  • Docusaurus 3
  • React
  • Mermaid diagrams
  • การเชื่อมต่อกับ Decap CMS
  • oidc-client-ts สำหรับการเข้าถึงของบรรณาธิการที่มีการป้องกัน

ทำไมจึงสำคัญ:

  • ให้ทั้งเอกสารสาธารณะของผลิตภัณฑ์และเอกสารสำหรับนักพัฒนา
  • รองรับเวิร์กโฟลว์การแก้ไขแบบมีการป้องกัน แทนการแก้เนื้อหาใน production โดยตรง

apps/web

แอปพลิเคชัน Next.js

บทบาทปัจจุบัน:

  • พื้นผิวเว็บรอง
  • ไม่ใช่เป้าหมายหลักของการส่งมอบสาธารณะในโมเดล infra ปัจจุบัน

จุดนี้สำคัญสำหรับผู้ที่เพิ่งเข้ามาอ่านรีโพ เพราะเส้นทางการส่งมอบหลักของ AIRS ตอนนี้เป็น Expo-web-first ไม่ใช่ Next.js-first

แพ็กเกจที่ใช้ร่วมกัน

@alternun/auth

แพ็กเกจ wrapper ด้านการยืนยันตัวตนที่ใช้ร่วมกัน

วัตถุประสงค์:

  • รวม abstraction ด้าน auth ฝั่งแอปไว้ที่เดียว
  • ห่อหุ้มไลบรารี auth ต้นทางที่โครงการใช้อยู่
  • เพิ่มพฤติกรรมไคลเอนต์ที่เหมาะกับมือถือ
  • มีสคริปต์สนับสนุนสำหรับ SES และอีเมลรอบงาน identity/email

@alternun/ui

แพ็กเกจคอมโพเนนต์ UI ที่ใช้ร่วมกัน

วัตถุประสงค์:

  • เก็บชิ้นส่วนอินเทอร์เฟซที่นำกลับมาใช้ซ้ำได้ให้อยู่นอกแอปเดียว
  • รองรับการใช้ซ้ำข้ามหลายแอปเมื่อภาษาการออกแบบใกล้กัน

@alternun/i18n

แพ็กเกจแคตตาล็อกคำแปลที่ใช้ร่วมกัน

วัตถุประสงค์:

  • เป็นศูนย์กลางของข้อมูล locale และตัวช่วย runtime
  • ให้แอปต่าง ๆ ใช้ร่วมกันแทนการคัดลอกไฟล์คำแปลหลายชุด

packages/email-templates

ส่วนสนับสนุนการสร้างและซิงก์อีเมล

วัตถุประสงค์:

  • จัดเก็บเนื้อหาอีเมลหลายภาษาที่ใช้ร่วมกัน
  • รองรับระบบส่งอีเมลปลายทาง เช่น การซิงก์เทมเพลต/อีเมลของ Supabase

@alternun/infra

แพ็กเกจด้านการปรับใช้และแพลตฟอร์ม

วัตถุประสงค์:

  • กำหนดทรัพยากร AWS
  • ควบคุมการจับคู่โดเมนและ stage
  • ดูแลการสร้าง pipeline และกลไกป้องกันการปรับใช้
  • ทำหน้าที่เป็นกระดูกสันหลังด้านปฏิบัติการของ monorepo

เครื่องมือหลัก

รีโพนี้ประสานงานด้วยชุดเครื่องมือขนาดเล็กแต่มี leverage สูง:

  • pnpm สำหรับจัดการแพ็กเกจใน workspace
  • TurboRepo สำหรับ orchestration ของ build graph
  • TypeScript ทั่วทั้ง monorepo
  • ESLint และ Prettier สำหรับวินัยของโค้ด
  • Husky และ lint-staged สำหรับการบังคับใช้ก่อน commit

โมเดล Build และงาน

ที่รากของรีโพ มีการทำให้คำสั่งหลักเป็นมาตรฐาน:

  • pnpm build
  • pnpm dev
  • pnpm lint
  • pnpm type-check
  • pnpm test

Turbo จะประสานงานงานเหล่านี้เพื่อให้ dependency ระหว่างแพ็กเกจถูก build ตามลำดับที่ถูกต้อง

สิ่งนี้ให้จุดสมดุลที่ใช้งานได้จริงกับทีม:

  • แอปแต่ละตัวสามารถพัฒนาแยกกันได้
  • แพ็กเกจที่ใช้ร่วมกันยังคงนำกลับมาใช้ได้
  • การเปลี่ยนแปลงแบบครอบคลุมหลายส่วนยังตรวจสอบได้จากคำสั่งชุดเดียวที่รากรีโพ

ทำไมโครงสร้างนี้จึงใช้ได้ผล

Monorepo นี้ถูกปรับให้เหมาะกับงานแบบ platform มากกว่างานแอปเดี่ยว

นั่นหมายความว่าโครงสร้างนี้ไม่ใช่เรื่อง "frontend กับ backend" เป็นหลัก แต่เน้นไปที่:

  • ประสบการณ์สาธารณะ
  • การปฏิบัติการภายใน
  • ขอบเขตของ identity และความไว้วางใจ
  • โครงสร้างพื้นฐานที่นำไป deploy ได้
  • ส่วนประกอบผลิตภัณฑ์ที่ใช้ร่วมกัน

สำหรับผู้มีส่วนร่วมจากภายนอก นี่คือโมเดลความคิดที่สำคัญที่สุดที่ควรมีไว้ขณะสำรวจโค้ดเบสนี้