ข้ามไปยังเนื้อหา

Frontend Init

แอปพลิเคชัน Next.js ที่ apps/web ใช้ App Router พร้อมโฟลเดอร์ app/ อยู่ระดับบนสุด (ไม่มี src/) ชี้ไปที่ NestJS API ผ่าน NEXT_PUBLIC_API_URL

Architecture เลือกใช้ App Router ไว้แล้ว: Server Component ดึงข้อมูลจาก GraphQL API บนฝั่งเซิร์ฟเวอร์ สำหรับเส้นทางอ่านที่เป็นสาธารณะและแคชได้ ส่วน Client Component ถือ session ของ admin ไว้สำหรับเส้นทางเขียนที่ยืนยันด้วย JWT ตัว create-next-app สร้างโครงสร้างแบบนั้นให้ตรง ๆ ไม่ต้องประกอบเองด้วยมือ

App Router เทียบกับ Pages Router App Router ให้ React Server Component — คอมโพเนนต์ที่รันบนเซิร์ฟเวอร์ ดึงข้อมูลได้ตรง ๆ และไม่ส่งโค้ดส่วนนั้นไปที่ browser เลย — บวกกับ layout ซ้อนกันและ revalidation ราย segment ซึ่งตรงกับโมเดล ISR ที่บทเรียน architecture อธิบายไว้พอดี ส่วน Pages Router รุ่นเก่าเรียบง่ายกว่าและไม่ต้องคิดเรื่องเส้นแบ่ง server/client component แต่ก็ไม่มี Server Component ให้ใช้เช่นกัน การดึงข้อมูลทุกครั้งจึงต้องไปเกิดใน getServerSideProps/getStaticProps หรือไม่ก็ฝั่ง client สำหรับคอร์สที่สร้างรอบ SSR/ISR App Router คือทางเลือกเดียวที่เป็นไปได้จริง

src/ เทียบกับไม่มี src/ โฟลเดอร์ src/ แยกโค้ดแอปออกจากไฟล์ config ระดับ root (next.config.ts, package.json) มีประโยชน์ในโปรเจกต์ใหญ่ที่มีไฟล์ระดับบนสุดเยอะ แต่ apps/web มี namespace อยู่ใน monorepo devblog/ อยู่แล้ว การแยกแบบนั้นจึงได้ประโยชน์น้อยลงมาก คอร์สนี้เลยวาง app/ ไว้ที่ระดับบนสุดของ apps/web แบบเดียวกันตลอดทุกบทเรียนที่แตะฝั่ง frontend

Scaffold แอปเข้าไปที่ apps/web แบบไม่โต้ตอบ:

Terminal window
cd devblog
npx create-next-app@latest apps/web --typescript --app --no-src-dir --no-tailwind --eslint --import-alias "@/*" --use-npm
cd apps/web

ติดตั้ง dependency สองตัวที่คอร์สนี้ต้องการเพิ่มเติมจากที่ create-next-app ติดตั้งให้แล้ว:

Terminal window
# graphql-request: a minimal client for calling the NestJS GraphQL API
# react-markdown + remark-gfm: render a post's Markdown body, including GFM tables/strikethrough
npm install graphql-request react-markdown remark-gfm

สร้าง apps/web/.env.local เพื่อให้แอปรู้ว่า API อยู่ที่ไหน:

NEXT_PUBLIC_API_URL=http://localhost:4000/graphql

ค่านี้ตรงกับ .env.example ที่ root จาก Repo layout ส่วน .env.local เป็นข้อตกลงของ Next.js ตัว .gitignore ของ scaffold ignore ให้อยู่แล้ว และไฟล์นี้ชนะไฟล์ env อื่น ๆ เสมอตอน dev ในเครื่อง

สตาร์ต dev server:

Terminal window
npm run dev
Open http://localhost:3000
# The default Next.js starter page loads, with a live-reloading dev server in the terminal

โครง app/ ที่ได้ สด ๆ จาก scaffold:

apps/web/
├── app/
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx # root layout — wraps every page, holds <html>/<body>
│ └── page.tsx # the "/" route
├── public/
├── .env.local
├── next.config.ts
├── package.json
├── tsconfig.json
└── eslint.config.mjs

(ไฟล์ที่ได้จริงอาจต่างกันนิดหน่อยตามเวอร์ชัน Next.js ที่คุณติดตั้ง จุดสำคัญคือต้องมีโฟลเดอร์ app/ ที่มี layout.tsx และ page.tsx)

apps/web คือโปรเจกต์ Next.js App Router ที่ scaffold ด้วย create-next-app --app --no-src-dir พร้อมติดตั้ง graphql-request และ react-markdown/remark-gfm ไว้เรียก API และเรนเดอร์เนื้อหาโพสต์ ค่า NEXT_PUBLIC_API_URL ใน .env.local ชี้ไปที่ http://localhost:4000/graphql ตรงกับพอร์ตของ API จาก Backend init และ npm run dev ยืนยันแล้วว่าบูตขึ้นที่พอร์ต 3000

ถัดไป: Compose skeleton →