Next.js คืออะไร? มาเริ่มเขียนเว็บด้วย Next.js กันดีกว่า
สวัสดีครับ บทความนี้จะพาไปรู้จักกับการเขียนเว็บด้วย Next.js กันนะครับ
ซึ่งบทความนี้เป็นบทความเริ่มต้นที่ผมสรุปมาให้อ่านกัน โดยที่ผมไม่ได้เชี่ยวชาญ Next.js นะครับ ตัวผมก็เพิ่งจะได้หัดใช้ Next.js มาไม่นาน 1-2 สัปดาห์ โดยทำโปรเจ็คเล็กๆเท่านั้น เมื่อก่อน เคยได้ยินมานานละ ได้อ่านบล็อกบ้าง คนอื่นๆ เล่าให้ฟังบ้าง แต่ไม่เคยลองจับ ลองเล่นจริงๆ วันนี้เลยลองมาบล็อก และเป็นการทบทวนตัวเองไปในตัวด้วย
สำหรับบทความนี้เนื้อหาเขียนเมื่อปี 2020 ครับ อาจจะมีข้อมูลที่ไม่ได้อัพเดท ตอนนี้ผมได้ทำการเขียนบทความใหม่ เป็นเวอร์ชั่น 2022 สามารถอ่านเพิ่มเติมได้ที่นี่ครับ บทความสอน Next.js อัพเดทเนื้อหา ปี 2022
Next.js คืออะไร?
Next.js เป็น React Web Framework คล้ายๆกัย Create React App ที่ช่วยให้เราเขียนเว็บได้สะดวกขึ้น เพราะเค้า Setup และ Config อะไรหลายๆ อย่างให้เราเรียบร้อยแล้ว เช่น
- Zero Config - เราไม่ต้อง Config อะไรเลย
- Ready for Production - พร้อมใช้งาน Production
- รองรับ SEO เพราะเป็น Server Side Rendering (SSR) (เทียบกับ React ปกติ ส่วนใหญ่จะเป็น Client Side Rendering)
- มีพวก Code Spliting ให้เลย
- ทำเป็น Static Site Generator (SSG) ได้ เช่นกัน
- หรือแม้แต่การทำ Dynamic Page, การทำ APIs หรือการ Custom Server ก็ทำได้เช่นกัน
รวมถึง Documentation อ่านค่อนข้างง่าย มี Example ให้ดูเยอะ เรียกได้ว่าใครที่เคยเขียน React มาก่อน ก็มาเริ่ม หรือใช้ Next.js ไม่ยากเลยครับ
Getting Started
ก่อนเริ่มเลย สิ่งที่ทุกคนควรจะมีคือ
- พื้นฐาน HTML & CSS & JS เบื้องต้น เคยเขียนเว็บมาบ้าง
- พื้นฐาน React.js มาบ้าง
- เนื้อหาเป็น Next.js 9.3 นะครับ (อาจจะมีเนื้อหาของเวอร์ชั่นก่อนหน้าบ้าง)
ถ้าได้แล้วก็ไปลุยกันเลยครับ
โดยก่อนที่จะเริ่ม จริงๆแล้ว ตัว Next.js เค้าก็มี Tutorial มาให้เราลองเรียน เป็น Getting Started เนื้อหาถือว่าครบถ้วนสำหรับผู้เริ่มต้นเลยครับ (เนื้อหาบางส่วนผมก็อ้างอิงจากทีนี่เช่นกัน) มีคำอธิบาย ลงรายละเอียด รวมถึงคำถาม Quiz เล็กๆ น้อยๆ ให้เราตอบ
สร้างโปรเจ็คขึ้นมาใหม่ครับ
จากนั้นติดตั้ง Next.js และ React
จากนั้น เพิ่มส่วนนี้ลงไปใน package.json
ดูให้แน่ใจว่า package.json
เราติดตั้ง Next เวอร์ชั่น 9.3 ขึ้นไปนะครับ
เพราะเวลาที่เราจะ Start server ด้วยคำสั่ง npm start
หรือ npm run dev
จะให้มันรัน คำสั่งของ next
นั่นเอง
Create Pages & Routing
ต่อมา ทำการสร้าง Page ขึ้นมา 2 หน้า ครับ คือ Index และ About ซึ่งใน Next.js นั้นมันจะทำ Auto Rouing ให้เราอัตโนมัติโดยไม่ต้องทำอะไรเลย แค่เราสร้าง React Component ไว้ในโฟลเดอร์ชื่อ pages
ก็พอ
เช่น ไฟล์ pages/index.js
เรามีหน้าตาประมาณนี้
และไฟล์ pages/about.js
เป็นแบบนี้
ทีนี้เมื่อเรา start server ขึ้นมา และเข้า url http://localhost:3000 และ http://localhost:3000/about เราก็จะเห็น Index และ About ทันที
การทำ Routing ระหว่าง Page สำหรับ Client Side Routing แบบ React Router ตัว Next ก็มีมาให้เลยคือ next/link
โดยหน้าตามัน ก็เป้น Wrapper Component ธรรมดาๆ แบบนี้
เราก็สามารถที่จะ Navigate ระหว่างหน้า แบบ React Router ได้เลย
Dynamic Page
เราทำ Routing แล้ว เราก็ทำ Dynamic Page ได้เช่นกัน ตัวอย่างเช่น เราอยากได้ routing กำหนดได้แบบ React Router เช่น
blogs/:id
- เพื่อแสดงเนื้อหา blog แต่ละบทความ
วิธีการทำคือ เราสร้างไฟล์ ชื่อ [id].js
ไว้ใน pages/blogs
ครับ
[]
จะเป็นการบอก Next.js ว่าให้ทำเป็น Dynamic Route
ในไฟล์นี้มี ข้อมูลแบบนี้
โดยเมื่อเป็น Dynamic Page ตัว Next.js สามารถอ่าน query.id
(ชื่อเดียวกับไฟล์ ที่ตั้งด้วย []) ได้เลยครับ โดยการ access ตัวออปเจ็ค router
ก็ใช้ useRouter()
เพื่อให้ได้ค่า router
นั่นเอง หากใครงง สามารถไปอ่านเรื่อง React Hook เพิ่มเติมได้นะครับ
ทีนี้เวลาเราเข้า url http://localhost:3000/blogs/1 หรือ http://localhost:3000/blogs/12345 เราก็จะได้ content ที่ต่างกันแล้ว
Step ถัดไป เพื่อนๆ ลองนำ id ที่ได้จาก url มาลองสร้างเป็น dynamic จริงๆ เช่น ไปหา id จาก array แล้วเอามาแสดงผล ถ้าไม่เจอ ก็โชว์ว่า not found แล้วกลับไปหน้า Home อะไรพวกนี้ดูครับ
Fetching API
ต่อมา นอกจาก Next.js จะทำเป็น Dynamic Pages ได้แล้ว ตัว Next.js เราก็ยังสามารถที่จะ Fetch APIs ได้ปกติครับ ทั้งจาก API ภายนอก และจาก API ของ Next.js เอง (ที่เดี๋ยวจะพูดในหัวข้อถัดไป)
ซึ่งตัวอย่าง นี้ผมจะทำการดึงข้อมูล meow แบบสุ่มครับ จาก url นี้ https://aws.random.cat/meow
ซึ่งเราจะใช้ความสามารถของ getInitialProps
นะครับ
จริงๆแล้ว ใน Next.js 9.3 ที่เพิ่งออกมาเลย วันนี้ เค้าแยก function ออกเป็น
getServerSideProps
และgetStaticProps
เลยครับ เพื่อแยกการ fetch ข้อมูลจาก static page หรือ server page นั่นเอง
ข้อควรรู้ของ getInitialProps
คือ ไม่สามารถใช้ใน children component ได้นะครับ ต้องอยู่ใน โฟลเดอร์ pages
เท่านั้น
ตัวอย่างการ fetch ข้อมูลแมว ครับ ผมสร้างไฟล์ชื่อ pages/meow.js
ดังนี้
fetch
ใช้isomorphic-unfetch
สำหรับ fetch ทั้ง Server/Client นะครับ ติดตั้งด้วยnpm install isomorphic-unfetch
API Routes
ใน Next.js เราสามารถทำตัวเป็น Backend APIs ได้เลย โดยที่ไม่ต้องมี Server เพิ่ม มองเป็น Serverless function ก็ได้ครับ โดยเพียงแค่สร้างโฟลเดอร์ api
ไว้ภายใน pages
ก็พอครับ เช่น
pages/api/posts.js
- เพื่อเอาไว้ get posts ทั้งหมด โดยเรียกด้วยGET /api/posts
pages/api/posts/[id].js
- เพื่อดึง post ตาม id มาแสดง โดยเรียกด้วยGET /api/posts/:id
ซึ่งสิ่งสำคัญของไฟล์ API คือ ต้อง export default
เป็น Handle function ครับ (ที่มี request และ response) ต่างจากหน้าปกติ ที่ต้องเป็น React Component แบบนี้
ให้มองว่ามันเหมือนกับ Handler ของ Express ครับ
ลองสร้าง API สำหรับ provide ข้อมูล blog posts สร้างไฟล์ชื่อ pages/api/posts.js
และ pages/api/posts/[id].js
โดยไฟล์ pages/api/posts.js
มีข้อมูลแบบนี้
ส่วนไฟล์ pages/api/posts/[id].js
เป็นแบบนี้
อย่าลืมสร้างไฟล์ mock/posts.js
ขึ้นมา จริงๆ ใช้พวก faker ก็ได้เช่นกันครับ
ทีนี้ API ของเรา สามารถ Access ได้ผ่าน http://localhost:3000/api/posts และ http://localhost:3000/api/posts/:id ได้เลยครับ
ลองเปลี่ยนจาก Fetch API meow มาเป็น API ที่สร้างจาก Next.js ด้วยกันเอง ก็ได้เลยครับ
Running Production
การ Deploy หรือ Run บน Production นั้นก็เหมือน Node.js ปกติเลยครับ หรือเราจะใช้ Hosting ของทาง Zeit ก็ได้เช่นกัน ทีมเดียวกับที่ทำ Next.js นั่นแหละ หรือ Heroku ก็ได้เช่นกันครับ
- Hosting กับ ZEIT Now
- Heroku - อาจจะต้องปรับ script start เพราะ Heroku มัน generator port จาก environment เช่น
"start": "next start -p $PORT"
หรือถ้าเรารัน VPS เอง หรือ Hosting เอง เราก็แค่รัน
เพื่อให้ Next มัน generate production เป็นโฟลเดอร์ .next
ขึ้นมา จากนั้นก็สั่ง start ได้เลย
หรือหากใช้พวก PM2 ก็ start PM2 เหมือน Node.js ปกติได้เลยครับ
Build Static
มาถึงเรื่องของ Buld Static กันครับ ปกติแล้ว Next.js ถ้าเราจะ build static นะครับ ซึ่งมันจะ generate HTML ตอน build time (เรารันด้วยคำสั่ง next build
) ซึ่ง Next.js ทำ static html ได้ด้วย การ generate HTML แบบทั้งมี data และไม่ต้องมี data ก็ได้ โดยใช้ getStaticProps
ครับ (ตัวก่อน Next.js 9.3 จะใช้แค่ getInitialProps
แล้ว Next.js จะไป handle เองว่า เป็น static หรือ server side)
ลองสร้างไฟล์ pages/meow_static.js
ขึ้นมา สำหรับไฟล์นี้ จะ fetch เฉพาะตอน build time ครับ
โดย getStaticProps
ต้อง export เป็น function และในส่วนของ return { props: {}}
จะกลายไปเป็น props ของ Component ทำให้เราสามารถเข้าถึง Meow = ({ meow })
ได้ครับ
เมื่อไหร่ที่ควรใช้ getStaticProps
? และข้อควรรู้
- เมื่อต้องการ dynamic data ตอน build time
getStaticProps
จะรันแค่ฝั่ง Server Side ครับ จะไม่รัน client side นั้นหมายความว่า code ส่วนนี้มันจะไม่ถูก bundle ไปด้วย (ซึ่งใน doc บอกเลยไว้ว่า เราสามารถ connect database ตรงนี้ได้เลยนะ )getStaticProps
ก็เหมือนgetInitialProps
คือใช้ได้แค่ในpages
เท่านั้น ไม่สามารถใช้กับ component ที่ไม่ใช่ page ได้- ใน development mode ตัว
getStaticProps
จะรันทุกๆ request ไม่ต้องแปลกใจ
ทีนี้ วิธีการ build static ก็ง่ายๆ เลยครับ ด้วย next export
เราอาจจะเพิ่มใน package.json
แบบนี้
จากนั้นก็รันด้วยคำสั่ง
จะได้โฟลเดอร์ out
เอาไป server static ได้ปกติเลย
อาจะใช้ Server ก็ได้ครับ
แล้วเปิด http://localhost:5000/meow_static.html หรือ http://localhost:5000/blogs/1.html
แต่เดี๋ยวก่อน! สังเกตเห็นมั้ยครับ ว่ามีบาง Route / Path ที่มันแสดงผลยังไม่ถูกต้อง เช่น blogs/:id
ถ้าเราต้องการ map พวก export path รวมถึง dynamic route เราต้องเซต exportPathMap
ใน next.config.js
ด้วยครับ ทำการสร้างไฟล์ next.config.js
ที่ Root folder เลย
แล้วลอง build export ใหม่ครับ เป็นอันเรียบร้อย
ซึ่ง เราไม่ได้ Export path ที่เป็น meow หรืออื่นๆ นะครับ ถ้าอยากให้เป็น static ด้วย ก็แค่ไปกำหนด exportPathMap
เพิ่มเติม จบปิ๊ง!
สรุป
ตัวอย่างนี้ก็เป็นเพียงแค่ Overview ให้เพื่อนๆ น้องๆได้รู้จักกับ Next.js นะครับ ก็พอจะมองเห็นภาพ มองเห็นแล้วว่า Next.js มันจะทำอะไรต่อได้บ้าง นอกจากนี้ ก็ยังมี Docs หรือ Example ที่ตัว Next.js เค้าทำไว้ให้เราอ่านเข้าใจมากๆ ครับ ไปหาอ่านเพิ่มเติมได้ครับ ส่วนผมเองก็หัดอ่าน และทำตาม Docs Tutorial อยู่เหมือนกันครับ
และถ้าเนื้อหาในบทความนี้ตรงไหนผิดพลาด ก็ขออภัยด้วยนะครับ และส่วนของ Next.js 9.3 เพิ่งมีบล็อออกมาเมื่อ 10 ชั่วโมงที่แล้ว ครับ อ่านได้ที่นี่ครับ
ตัวอย่าง Source Code ที่ใช้ในบทความนี้ครับ
สำหรับบล็อกนี้ก็ขอลากันไปเพียงเท่านี้ เจอกันบล็อกหน้าครับ
❤️ Happy Coding
- Authors
-
Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust