Babel Coder

มีอะไรใหม่บ้างใน Next.js 9

beginner

เป็นเวลากว่า 1 วันแล้วที่ Next.js ได้ปล่อยเวอร์ชัน 9 ออกมา คงถึงเวลาที่เราต้องอัพเดทกันแล้วซินะครับ ถ้างั้นไปดูสรุปสั้น ๆ จาก Next.js 9 กันดีกว่าว่ามีฟีเจอร์อะไรใหม่ ๆ บ้าง

สารบัญ

Dynamic Routing จะไม่ใช่เรื่องยากอีกต่อไป

เราทราบกันดีว่าถ้า URL ของเราคือ /articles/intro-to-nextjs เราจำเป็นต้องสร้างไฟล์ intro-to-nextjs.js ใต้โฟลเดอร์ pages/articles การทำงานถึงจะถูกต้อง แต่หาก URL ของเราเป็น /articles/:slug โดยส่วนของ :slug สามารถเปลี่ยนแปลงได้ เราจะต้องออกแบบโฟลเดอร์ pages อย่างไรให้ Next.js เข้าใจ?

วิธีดั้งเดิมของ Next.js นั้นเราต้องทำการ ปรับแต่งเซิฟเวอร์ ด้วยตนเองซึ่งเป็นอะไรที่ค่อนข้างยุ่งยาก แพคเกจอย่าง next-routes จึงดูเป็นทางออกมากกว่า

สำหรับ Next.js 9 ที่พึ่งคลอดนั้นสนับสนุนการทำงานแบบ Dynamic Routing แต่ต้น ไม่แน่ใจว่าได้แรงบันดาลใจมาจาก Nuxt.js ของ Vue ที่ทำแบบนี้มาได้ชาติเศษแล้วรึเปล่า เพราะตัววิธีการนั้นมีความคล้ายคลึงกัน

สำหรับ Next นั้นถ้าอยากได้ URL เป็น /articles/:slug สิ่งที่เราต้องทำคือสร้างโฟลเดอร์ pages/articles/[slug].js จุดสำคัญอยู่ที่ส่วนเปลี่ยนแปลงได้ (dynamic segment) ต้องนิยามใต้เครื่องหมาย [] Next ไม่ได้จำกัดว่าคุณจะมี dynamic segment กี่จุดขอแค่ทุกจุดอยู่ใต้ [] ก็พอ เช่น /articles/[articleSlug]/comments/[commentId].js ประกอบด้วย dynamic segments สองจุดคือ :articleSlug ที่เป็นชื่อโฟลเดอร์ และ :commentId ที่เป็นไฟล์

การจะดึงส่วนของ dynamic segments มาใช้นั้น ให้ดึงจากค่าของ query ออกมาได้เลยครับ เช่น

// URL: /articles/intro-to-next
// File: pages/articles/[slug].js
static async getInitialProps({ query }) {
  // slug = 'intro-to-next'
  const { slug } = query

  // นำค่า slug ไปใช้งานต่อได้
}

สร้างส่วนของ Backend API ใน Next.js ได้เลย

บางครั้งเราอยากสร้างส่วนของ API ผูกติดไว้กับการทำ Server-Side Rendering (SSR) ของ Next.js เราจึงทำการ ปรับแต่งเซิฟเวอร์ เพิ่มเติมให้ทั้งทำงานแบบ SSR ของ Next และสนับสนุนการให้บริการ API ที่เราเขียนเพิ่มเติม

Next 9 นั้นเพียงแค่เราสร้างโฟลเดอร์ api ภายใต้โฟลเดอร์ pages เราจะสามารถเรียกใช้ไฟล์ภายใต้ pages/api นั้นได้เสมือนเป็น API ของเรา เช่นสร้างไฟล์ชื่อ pages/api/articles.js เราจะได้ URL ไว้เรียกใช้คือ /api/articles

แน่นอนว่าการสร้างโฟลเดอร์และไฟล์นั้นอยู่ใต้ pages เราจึงสามารถใช้ [] เพื่อทำ dynamic routing ได้ด้วย เช่น URL ที่ระบุเป็น /api/articles/intro-to-next จะเข้าเรียกไฟล์ pages/api/articles/[slug].js เป็นต้น

สิ่งหนึ่งที่ไฟล์ใต้ api แตกต่างจากเพจทั่วไปคือต้องคืนกลับเป็น request handler function ไม่ใช่ React Component เช่น

// pages/api/articles.js
export default function handle(req, res) {
  res.json({ articles: [] })
}

Next 9 นั้นจะใช้เทคนิคของ Intersection Observer เพื่อทำการ Prefetch Link ที่ปรากฎบนหน้าจอแล้ว ความหมายคือถ้าเรามี Link อยู่ในเพจของเรา แต่ Link นั้นยังไม่โผล่เข้ามาในส่วนแสดงผล (Viewport) Next ก็จะยังไม่ทำอะไร หากแต่เมื่อสิ่งนั้นปรากฎบน Viewport แล้วไซร์ Next.js ก็จะทำการ Prefetch ข้อมูลล่วงหน้า เมื่อผู้ใช้งานตัดสินใจคลิกลิงก์นี้ในภายหลังจะทำให้รู้สึกโหลดไวขึ้น เพราะ assets ที่จำเป็นนั้นถูกโหลดมาแล้ว

เราป้องกันการทำ prefetch ได้ด้วยการระบุค่า false ลงไปใน Link ดังนี้

<Link href="/terms" prefetch={false}>
  <a>About US</a>
</Link>

สร้าง static pages ควบคู่ไปกับการทำ server-side rendeing แบบอัตโนมัติ

static site นั้นเร็ว Next.js ก็สนับสนุนการสร้าง static site ผ่านตัวมันมานานแล้วเช่นกัน แต่นั่นทำให้คุณต้องเลือก เพราะถ้าคุณสร้างเว็บไซต์แบบ static ด้วย Next แล้ว คุณจะทำ server-side rendering ไปด้วยไม่ได้

ทำไมฉันต้องเลือกหละ? Next 9 ตัดสินใจที่จะพิจารณาส่วนของ getInitialProps จากไฟล์ต่าง ๆ ในโฟลเดอร์ pages หากไฟล์ไหนไม่ได้มีการ “หยุด” การทำงานเพื่อไปรอการร้องขอข้อมูลจาก API server นั่นแสดงว่าไฟล์นี้ทำเป็น static page ได้ Next จะดำเนินการสร้างไฟล์นี้ให้เป็น static page ในขณะที่เพจอื่นที่ยังต้องการรอข้อมูลจาก API มาทำ SSR ก็ยังคงได้รับการทำงานแบบ SSR จาก Next เช่นเดิม

ไม่ยุ่งยากกับการใช้ TypeScript อีกต่อไป

ไม่จำเป็นต้องใช้ @zeit/next-typescript ตั้งค่า .babelrc หรือ next.config.js อีกต่อไป เพราะ Next.js จะจัดการไฟล์ TypeScript ให้กับคุณอัตโนมัติ เพียงแค่เปลี่ยนนามสกุลไฟล์จาก .js เป็น .tsx แถมยังสร้างไฟล์ tsconfig.json ให้อัตโนมัติด้วยหากในโปรเจคของเราไม่มีไฟล์นี้มาก่อน

อื่น ๆ

Next.js 9 นั้นไม่ได้มีแค่สิ่งที่ผมได้แสดงในบทความนี้ หากแต่ยังมีการปรับปรุงประสิทธิภาพอื่น ๆ อีกมาก เช่น

  • มีการแสดงผลไอคอนเล็ก ๆ ด้านล่างขวาของเพจเมื่อมีการคอมไพล์โค้ดใหม่
  • ลบโค้ดของเซิฟเวอร์ที่ไม่ได้ใช้ออกไปจากโค้ดส่วนไคลเอนต์ ทำให้ bundle size ของไคลเอนต์มีขนาดเล็กลง
  • เพิ่มประสิทธืภาพการทำงานกับ AMP
  • การรายงานข้อมูลของการ build ที่ดีขึ้น

การปรับปรุงประสิทธิภาพที่น่าสนใจในอนาคต

Google ได้ร่วมมือกับ Next ด้วยการเสนอ RFC และ pull requests ที่ช่วยปรับปรุงประสิทธิภาพของ Next มีหลายตัวมากที่น่าสนใจครับ และตัวอย่างหนึ่งที่อยากนำเสนอก็คือ module/nomodule pattern

เราทราบกันดีว่ามีหลายสิ่งที่เราต้องการเขียนแต่ไม่สนับสนุนให้ทำในเบราเซอร์รุ่นเก่า แต่นั่นไม่เป็นปัญหาสำหรับเบราเซอร์ที่ใหม่กว่า เช่น เบราเซอร์เก่า ๆ ไม่สนับสนุนการทำงานกับ Async/Await แต่เบราเซอร์ยุคใหม่นั้นสนับสนุน ครั้นจะเอา polyfills ใส่ลงไปเพื่อให้เบราเซอร์เก่าทำงานได้ มันกลับเป็นหอกสองคมที่เบราเซอร์ใหม่ต้องรับภาระในการโหลดโค้ดส่วนเกิดแทน Next จึงมี RFC ที่เสนอให้ใช้หลักการของ module/nomodule pattern เพื่อสร้าง build แยกสำหรับเบราเซอร์ใหม่และเก่า ซึ่งหลักการนี้ทำมาใน Vue/Nuxt.js มาสามชาติเศษแล้ว

สรุป

Next.js 9 นั้นยังมีการปรับปรุงเรื่องอื่นอีก เพื่อน ๆ ที่สนใจสามารถเข้าไปอ่านได้จากเอกสารอ้างอิงท้ายบทความครับ

เอกสารอ้างอิง

Next.js 9. Retrieved July, 9, 2019, from https://nextjs.org/blog/next-9


แสดงความคิดเห็นของคุณ


Teeraphong M Chaichalermpreecha4 เดือนที่ผ่านมา

มีไอเดียการเปลี่ยน path directory api ที่อยู่ใน pages ให้ออกมาอยู่ข้างนอก level เดียวกับ components, pages directory ไหมครับ แล้วอยากเปลี่ยนชื่อเป็น apis ด้วย


Kittiew Von6 เดือนที่ผ่านมา

Nextjs สามารถทำ router ที่เป็น post method ด้วย server Hapi โดยใช้ nexthandler ได้ป่าวอ่าคะ