วิธีอ่านโค้ด Next.js ที่คุณไม่ได้เขียนเอง
ทุกโมดูลก่อนหน้านี้สอนให้คุณ เขียน Next.js โมดูลนี้สอนอีกครึ่งหนึ่งของงาน คือการอ่านโค้ด Next.js ที่คนอื่น — หรือ AI — เขียนไว้ แล้วตัดสินว่ามันถูกต้องหรือไม่ AI assistant จะส่งโค้ดที่ compile ผ่าน, next build ยอมรับ, และหน้าตาเหมือนตัวอย่าง App Router ที่คุณเรียนมาทุกประการ แต่ไม่มีข้อไหนพิสูจน์ว่ามันถูกต้อง ความล้มเหลวของ Next.js เองมักจะเงียบผิดปกติ: หน้าที่ควรเป็น static กลายเป็น dynamic แบบเงียบๆ, prop ที่ควรพังดังๆ กลับ serialize เป็น undefined, action ที่ไม่มีการตรวจ auth เลย build และ deploy ได้โดยไม่มี warning สักคำ ห้าขั้นตอนด้านล่างคือลำดับที่ทำให้ความล้มเหลวเหล่านี้ปรากฏออกมาจริงๆ และทุกบทถัดไปในโมดูลนี้จะเจาะลึกทีละส่วน
flowchart TD A["1. Boundaries<br/>'use client' / 'use server' placement"] --> B["2. Caching model<br/>segment config vs cacheComponents"] B --> C["3. Auth<br/>inside every action and route handler"] C --> D["4. Error and redirect path<br/>try/catch around redirect()/notFound()"] D --> E["5. Config<br/>next.config.ts, env vars"]
1. Boundary: 'use client' และ 'use server' อยู่ตรงไหน
หัวข้อที่มีชื่อว่า “1. Boundary: 'use client' และ 'use server' อยู่ตรงไหน”ก่อนจะอ่านว่า component ทำ อะไร ให้อ่านก่อนว่ามันรันอยู่ฝั่งไหนของ network "use client" ไม่ได้ทำเครื่องหมายแค่ component เดียว — มันทำเครื่องหมาย entry point ของทั้ง subtree ใน module graph และทุกอย่างที่ import ไปถึงจากจุดนั้นจะถูกส่งไปที่ browser ส่วน "use server" ทำเครื่องหมายฟังก์ชันที่ compile ออกมาเป็น public HTTP endpoint ที่ใครก็เรียกได้ถ้ามี action ID ไม่ใช่แค่ form ของคุณเท่านั้น
- สิ่งที่ต้องมองหา: ไฟล์ (หรือ parent ที่ใกล้ที่สุด) ที่มี
'use client'หรือ'use server'เป็นบรรทัดแรก; ทุก prop ที่ส่งจาก Server Component ไปยัง Client Component; ทุก hook (useState,useRouter,useFormStatus) และตรวจว่าไฟล์ที่เรียกมันเป็น Client Component จริงหรือไม่ - คำถามที่ต้องถาม: directive นี้อยู่ต่ำในต้นไม้เท่าที่ควรหรือเปล่า หรือมันถูกวางไว้ที่ layout/page ใกล้ราก เพราะเป็นวิธีที่ทำให้ error หายไปง่ายที่สุด
- บทที่อธิบายเรื่องนี้: Server and Client Components สำหรับกฎเรื่อง subtree และ serialization boundary; Server Actions คืออะไร สำหรับเหตุผลที่ทุก action เป็น public endpoint ทันทีที่มันถูก export
2. Caching model ที่ project นี้ใช้จริง
หัวข้อที่มีชื่อว่า “2. Caching model ที่ project นี้ใช้จริง”Next.js มี caching model สองแบบตลอดช่วงอายุของมัน และ project หนึ่งจะรันแค่แบบเดียวในเวลาหนึ่ง: Route Segment Config (dynamic, revalidate, fetchCache, dynamicParams, runtime — model ที่ tutorial ก่อน 16 ทุกอันสอน) หรือ Cache Components (cacheComponents: true ใน next.config.ts, 'use cache', cacheLife, cacheTag) ทั้งสองแบบใช้ร่วมกันไม่ได้ — ทุก export ของ Route Segment Config จะทำให้ next build พังทันทีที่ cacheComponents เปิดอยู่ โค้ดที่ AI เขียนมักผสมคำศัพท์จากทั้งสอง model เพราะทั้งคู่ปรากฏใน training data ของมัน
- สิ่งที่ต้องมองหา: เปิด
next.config.tsก่อนอ่าน route ไหนเลย และเช็คว่ามีcacheComponents: trueหรือไม่ จากนั้นเช็คว่า route ใช้export const dynamic = .../export const revalidate = ...(model เก่า) หรือ'use cache'/cacheLife(...)/cacheTag(...)(model ใหม่) - คำถามที่ต้องถาม: ทุกไฟล์สอดคล้องกับสิ่งที่
next.config.tsบอกไว้หรือเปล่า หรือไฟล์นี้สมมติว่าใช้ model อีกแบบ - บทที่อธิบายเรื่องนี้: Route Segment Config and Runtimes สำหรับ model เก่าและ error ที่บอกว่าใช้ร่วมกันไม่ได้;
use cacheและ Cache Components และ Partial Prerendering สำหรับ model ใหม่
3. Auth ในทุก action และทุก route handler
หัวข้อที่มีชื่อว่า “3. Auth ในทุก action และทุก route handler”Server Action คือ POST endpoint; Route Handler คือ HTTP method อะไรก็ตามที่คุณ export ทั้งคู่ไม่ได้รับการป้องกันสืบทอดมาจากหน้าที่ render ปุ่มชี้ไปหามัน — การซ่อน UI ตอน render (โชว์ปุ่มลบให้แค่ admin) ควบคุมแค่ว่า UI แสดงอะไร ไม่ได้ควบคุมว่าใคร curl เข้า endpoint ตรงๆ ได้
- สิ่งที่ต้องมองหา: บรรทัดแรกๆ ของทุกฟังก์ชันใน
app/actions.ts, ไฟล์'use server'ใดๆ, และทุกapp/**/route.tsมองหาการเช็ค session (pattern DAL ของคอร์สนี้คือverifySession()) ก่อนอ่านหรือเขียนใดๆ และมองหาว่าการเขียนกรองด้วย ID ของ user ปัจจุบันด้วย ไม่ใช่แค่เช็คว่า มีใครสักคน login อยู่ - คำถามที่ต้องถาม: ถ้าฉันส่ง request แบบนี้ด้วย
curlพร้อม session cookie ของคนอื่น ข้อมูลของใครจะถูกแก้ไข - บทที่อธิบายเรื่องนี้: Server Actions คืออะไร และ Security and Patterns; Authentication Patterns สำหรับตัว DAL เอง
4. Error และ redirect path
หัวข้อที่มีชื่อว่า “4. Error และ redirect path”redirect() กับ notFound() ไม่ได้ return — มัน throw error ควบคุม flow พิเศษของ Next.js (NEXT_REDIRECT / NEXT_HTTP_ERROR_FALLBACK) ที่ framework จะดักจับสูงขึ้นไปในต้นไม้ try/catch ที่ครอบโค้ดที่เรียกอันใดอันหนึ่งจะดักจับ throw ภายในนี้ไปด้วย ถ้ามันไม่ตั้งใจ re-throw ออกไป — และความผิดพลาดนี้มองไม่เห็นตอน development เพราะหน้ามักจะ render อะไรบางอย่างออกมาอยู่ดี
- สิ่งที่ต้องมองหา: ทุก
try { … } catch { … }block; มันมีการเรียกredirect()หรือnotFound()อยู่ข้างในไหม ไม่ว่าจะตรงๆ หรือผ่าน helper อย่างverifySession();catchblock log แล้วกลืนไปเลย หรือเรียกunstable_rethrow(err)/ re-throw - คำถามที่ต้องถาม: ถ้าฉันยิงเข้า code path นี้กับ server ที่รันจริง มันตอบกลับด้วย redirect / 404 จริงไหม — หรือตอบ 200 พร้อม body ที่ผิด
- บทที่อธิบายเรื่องนี้: Mutations and Revalidation ซึ่งพิสูจน์ความล้มเหลวแบบนี้กับ server จริง
5. Config: next.config.ts และ environment variables
หัวข้อที่มีชื่อว่า “5. Config: next.config.ts และ environment variables”สิ่งสุดท้ายที่ควรอ่าน เพราะมันเปลี่ยนความหมายของทุกอย่างข้างบน next.config.ts ตัดสินว่า caching model ไหนกำลังทำงาน (ขั้นที่ 2) และ flag ทดลองอะไรเปิดอยู่; ไฟล์ .env* ตัดสินว่าตัวแปรไหนใช้ได้ที่ไหน และมีแค่ตัวแปรที่ขึ้นต้นด้วย NEXT_PUBLIC_ — ที่เข้าถึงแบบ static literal process.env.NEXT_PUBLIC_X — เท่านั้นที่ปลอดภัยพอจะให้โค้ดฝั่ง browser เข้าถึงได้
- สิ่งที่ต้องมองหา:
cacheComponents,reactCompiler,turbopack.*ในnext.config.ts; ทุกการอ่านprocess.env.*ในไฟล์ที่มี (หรือ import เข้า)'use client'; ทุกตัวแปรที่ขึ้นต้นNEXT_PUBLIC_และมันเก็บอะไรอยู่จริงๆ - คำถามที่ต้องถาม: ตัวแปรนี้จำเป็นต้องไปถึง browser จริงไหม — และถ้าจำเป็น ฉันยังสบายใจไหมถ้ามันโผล่เป็น plain text ในไฟล์
.next/static/chunks/*.jsที่ใครก็ดาวน์โหลดได้ - บทที่อธิบายเรื่องนี้: Environment and Configuration; Middleware and the Request Lifecycle สำหรับ
proxy.tsและ config ระดับ request-time ที่รันก่อนทุกอย่างข้างบน
Mental Model
หัวข้อที่มีชื่อว่า “Mental Model”ลำดับการอ่าน route ของ Next.js ที่คุณไม่ได้เขียนเอง:
1. Boundaries → 'use client' / 'use server' อยู่ตรงไหน และดึงอะไรเข้ามาด้วย2. Caching model → segment config หรือ cacheComponents — project นี้ใช้อันไหน?3. Auth → ทุก action/route handler เช็ค session แล้วกรองเจ้าของ row ด้วยไหม?4. Error/redirect→ มี try/catch ที่ไหนกลืน redirect()/notFound() ไปหรือเปล่า?5. Config/env → flag ใน next.config.ts และตัวแปรไหนไปถึง browser
การข้ามไปดูแค่ "build ผ่านไหม" ตอบคำถามเหล่านี้ไม่ได้เลย — ทั้งห้าข้อ compile ผ่านหมดความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”- “ถ้า
next buildผ่าน แปลว่าโค้ดถูกต้อง” ทุกรูปแบบความล้มเหลวในแคตตาล็อกของโมดูลนี้ build ผ่านทั้งหมดnext buildพิสูจน์แค่ว่าโค้ดเป็น Next.js ที่ syntax ถูกต้อง ไม่ได้พิสูจน์ว่ามันปลอดภัยหรือทำงานตามที่ตั้งใจ - “แค่โค้ดในฟอร์มเท่านั้นที่สำคัญสำหรับ Server Action” action ถูกเรียกได้จาก ID ของมันจากที่ไหนก็ได้ ไม่ขึ้นกับฟอร์มที่บังเอิญเรียกมัน — ดูขั้นที่ 3
- “
try/catchครอบโค้ดเสี่ยงๆ ปลอดภัยกว่าเสมอ” รอบการเรียกredirect()หรือnotFound()การcatchแบบไม่มีเงื่อนไข อันตรายกว่า: มันเปลี่ยน redirect/404 ที่สะอาดให้กลายเป็น response 200 ที่ผิดแบบเงียบๆ - “ถ้าคนเขียนเอง ต้องการความระมัดระวังน้อยกว่า AI” ทุก pattern ในแคตตาล็อกของโมดูลนี้ก็ปรากฏในโค้ด Next.js ที่คนเขียนเองเหมือนกัน AI แค่ผลิตมันด้วยความมั่นใจที่สูงกว่าและปริมาณที่มากกว่า