วิธีสร้างบล็อกด้วย Next และ MDX

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ ในคู่มือนี้ เราจะดู Next.js ซึ่งเป็นเฟรมเวิร์ก React ยอดนิยมที่มอบประสบการณ์นักพัฒนาที่ยอดเยี่ยม และมาพร้อมกับฟีเจอร์ทั้งหมดที่คุณต้องการสำหรับการผลิต เราจะสร้างบล็อกทีละขั้นตอนโดยใช้ Next.js และ MDX สุดท้าย เราจะอธิบายว่าทำไมคุณถึงเลือกใช้ Next.js แทนที่จะเป็น “vanilla” React และทางเลือกอื่น เช่น Gatsby

Next.js เป็นเฟรมเวิร์ก React ที่ช่วยให้คุณสร้างแอปแบบสแตติกและไดนามิกได้อย่างรวดเร็ว มันพร้อมสำหรับการผลิตและรองรับการเรนเดอร์ฝั่งเซิร์ฟเวอร์และการสร้างไซต์แบบคงที่โดยทันที ทำให้แอป Next.js รวดเร็วและเป็นมิตรกับ SEO

ในบทช่วยสอนนี้ ก่อนอื่นฉันจะอธิบายอย่างชัดเจนว่า Next.js คืออะไรและทำไมคุณถึงใช้มันแทน Create React App หรือ Gatsby จากนั้น ฉันจะแสดงวิธีสร้างบล็อกที่คุณสามารถเขียนและแสดงโพสต์โดยใช้ Next.js และ MDX

ในการเริ่มต้น คุณจะต้องมีประสบการณ์กับ React ความรู้เกี่ยวกับ Next.js จะมีประโยชน์แต่ไม่จำเป็น บทแนะนำนี้จะเป็นประโยชน์กับผู้ที่ต้องการสร้างบล็อก (ส่วนบุคคลหรือองค์กร) โดยใช้ Next.js หรือยังคงค้นหาสิ่งที่จะใช้

มาดำดิ่งกัน

Next.js คืออะไร?

Next.js เป็นเฟรมเวิร์ก React ที่สร้างและดูแลโดย Vercel มันสร้างด้วย React, Node.js, Babel และ Webpack มันพร้อมสำหรับการผลิตเพราะมันมาพร้อมกับคุณสมบัติที่ยอดเยี่ยมมากมายที่มักจะถูกตั้งค่าในแอพ "วานิลลา" React

กรอบงาน Next.js สามารถแสดงแอปบนเซิร์ฟเวอร์หรือส่งออกแบบคงที่ ไม่ต้องรอให้เบราว์เซอร์โหลด JavaScript เพื่อแสดงเนื้อหา ซึ่งทำให้แอป Next.js เป็นมิตรกับ SEO และรวดเร็วอย่างเห็นได้ชัด

เหตุใดจึงต้องใช้ Next.js มากกว่าสร้างแอป React

Create React App เป็นเครื่องมือที่มีประโยชน์ซึ่งมีการตั้งค่าบิลด์ที่ทันสมัยโดยไม่มีการกำหนดค่าและไม่ต้องยุ่งยากกับการตั้งค่า Webpack, Babel และอื่นๆ หรือต้องรักษาการพึ่งพา เป็นวิธีที่แนะนำในการสร้างแอป React ในปัจจุบัน มีเทมเพลตสำหรับ TypeScript และยังมาพร้อมกับ React Testing Library

อย่างไรก็ตาม หากคุณต้องการสร้างแอปแบบหลายหน้า คุณจะต้องติดตั้งไลบรารีเพิ่มเติม ราวกับว่าคุณกำลังแสดงแอป React บนเซิร์ฟเวอร์ การตั้งค่าพิเศษอาจเป็นปัญหา และแพ็คเกจที่ติดตั้งไว้สามารถเพิ่มขนาดบันเดิลสุดท้ายของแอปของคุณได้

นี่เป็นปัญหาที่ Next.js ตั้งใจจะแก้ไข มอบประสบการณ์นักพัฒนาที่ดีที่สุด พร้อมทุกสิ่งที่คุณต้องการสำหรับการผลิต มันมาพร้อมกับคุณสมบัติเจ๋ง ๆ หลายประการ:

  • การส่งออกแบบคงที่ (การแสดงผลล่วงหน้า)
    Next.js อนุญาตให้คุณส่งออกแอป Next.js ณ เวลาสร้างเป็น HTML แบบคงที่ที่ทำงานโดยไม่มีเซิร์ฟเวอร์ เป็นวิธีที่แนะนำในการสร้างเว็บไซต์ของคุณเนื่องจากเสร็จสิ้นในเวลาที่สร้างและไม่ได้ทำตามคำขอแต่ละครั้ง
  • การแสดงผลฝั่งเซิร์ฟเวอร์ (การแสดงผลล่วงหน้า)
    มันแสดงหน้าล่วงหน้าเป็น HTML บนเซิร์ฟเวอร์ทุกคำขอ
  • แยกรหัสอัตโนมัติ
    ต่างจาก React ตรงที่ Next.js จะแยกโค้ดโดยอัตโนมัติและโหลดเฉพาะ JavaScript ที่จำเป็นเท่านั้น ซึ่งทำให้แอปทำงานได้รวดเร็ว
  • การกำหนดเส้นทางตามระบบไฟล์
    Next.js ใช้ระบบไฟล์เพื่อเปิดใช้งานการกำหนดเส้นทางในแอป หมายความว่าทุกไฟล์ในไดเร็กทอรี pages จะถือว่าเป็นเส้นทางโดยอัตโนมัติ
  • กำลังโหลดรหัสใหม่
    Next.js อาศัย React Fast Refresh เพื่อรีโหลดโค้ดของคุณใหม่ มอบประสบการณ์นักพัฒนาที่ยอดเยี่ยม
  • ตัวเลือกการจัดแต่งทรงผม
    เฟรมเวิร์ก Next.js มีการรองรับในตัวสำหรับ Styled JSX, โมดูล CSS, Sass, LESS และอื่นๆ

Next.js กับ Gatsby

Gatsby เป็นเครื่องกำเนิดไซต์แบบคงที่ที่สร้างขึ้นบน React และ GraphQL เป็นที่นิยมและมีระบบนิเวศขนาดใหญ่ที่มีธีม ปลั๊กอิน สูตรอาหาร และอื่นๆ

เว็บไซต์ Gatsby และ Next.js นั้นเร็วมากเพราะแสดงผลทั้งบนเซิร์ฟเวอร์หรือแบบสแตติก หมายความว่าโค้ด JavaScript ไม่รอให้เบราว์เซอร์โหลด มาเปรียบเทียบกันตามประสบการณ์ของนักพัฒนา

Gatsby นั้นง่ายต่อการเริ่มต้น โดยเฉพาะอย่างยิ่งถ้าคุณรู้จัก React อยู่แล้ว อย่างไรก็ตาม Gatsby ใช้ GraphQL เพื่อสืบค้นข้อมูลและเพจในเครื่อง การใช้ Gatsby เพื่อสร้างบล็อกง่ายๆ นี้อาจเกินความสามารถเพราะ GraphQL มีช่วงการเรียนรู้ และเวลาในการสืบค้นและการสร้างของหน้าคงที่จะนานขึ้นเล็กน้อย หากคุณสร้างบล็อกเดียวกันนี้สองครั้ง ครั้งแรกด้วย Gatsby และ Next.js บล็อกที่สร้างด้วย Next.js จะเร็วกว่ามากเมื่อสร้างเสร็จ เนื่องจากใช้ JavaScript ปกติในการสืบค้นข้อมูลและหน้าเว็บในเครื่อง

ฉันหวังว่าคุณจะใช้ประโยชน์จากพลังของเฟรมเวิร์ก Next.js และดูว่าเหตุใดจึงสะดวกกว่าทางเลือกอื่น นอกจากนี้ยังเป็นตัวเลือกที่ดีหากเว็บไซต์ของคุณต้องพึ่งพา SEO เป็นอย่างมาก เนื่องจากแอปของคุณจะรวดเร็วและง่ายดายสำหรับหุ่นยนต์ของ Google ในการรวบรวมข้อมูล นั่นเป็นเหตุผลที่เราจะใช้ Next.js ในบทความนี้เพื่อสร้างบล็อกด้วยไลบรารี MDX

เริ่มต้นด้วยการตั้งค่าแอป Next.js ใหม่

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

การตั้งค่า

มีสองวิธีในการสร้างแอป Next.js เราสามารถตั้งค่าแอพใหม่ด้วยตนเองหรือใช้ Create Next App เราจะไปอย่างหลังเพราะมันเป็นวิธีที่แนะนำ และจะตั้งค่าทุกอย่างให้เราโดยอัตโนมัติ

ในการเริ่มแอปใหม่ ให้เรียกใช้สิ่งต่อไปนี้ในอินเทอร์เฟซบรรทัดคำสั่ง (CLI):

 npx create-next-app

เมื่อเริ่มต้นโปรเจ็กต์แล้ว ให้จัดโครงสร้างแอป Next.js ดังต่อไปนี้:

 src ├── components | ├── BlogPost.js | ├── Header.js | ├── HeadPost.js | ├── Layout.js | └── Post.js ├── pages | ├── blog | | ├── post-1 | | | └── index.mdx | | ├── post-2 | | | └── index.mdx | | └── post-3 | | └── index.mdx | ├── index.js | └── \_app.js ├── getAllPosts.js ├── next.config.js ├── package.json ├── README.md └── yarn.lock

อย่างที่คุณเห็น โครงการของเรามีโครงสร้างไฟล์ที่เรียบง่าย มีสามสิ่งที่ควรทราบ:

  • _app.js ช่วยให้เราผนวกเนื้อหาบางส่วนเข้ากับองค์ประกอบ App.js เพื่อให้เป็นสากล
  • getAllPosts.js ช่วยให้เราดึงข้อมูลบล็อกโพสต์จากโฟลเดอร์ pages/blog อย่างไรก็ตาม คุณสามารถตั้งชื่อไฟล์อะไรก็ได้ที่คุณต้องการ
  • next.config.js เป็นไฟล์กำหนดค่าสำหรับแอป Next.js ของเรา

ฉันจะกลับมาที่แต่ละไฟล์ในภายหลังและอธิบายว่ามันทำอะไร ตอนนี้เรามาดูแพ็คเกจ MDX กัน

การติดตั้งไลบรารี MDX

MDX คือรูปแบบที่ช่วยให้เราเขียน JSX และนำเข้าส่วนประกอบลงในไฟล์ Markdown ได้อย่างราบรื่น ช่วยให้เราสามารถเขียน Markdown ปกติและฝังส่วนประกอบ React ในไฟล์ของเราได้เช่นกัน

ในการเปิดใช้งาน MDX ในแอป เราจำเป็นต้องติดตั้ง @mdx-js/loader ในการทำเช่นนั้น ก่อนอื่นให้ไปที่รูทของโปรเจ็กต์ จากนั้นรันคำสั่งนี้ใน CLI:

 yarn add @mdx-js/loader

หรือหากคุณใช้ npm:

 npm install @mdx-js/loader

ถัดไป ติดตั้ง @next/mdx ซึ่งเป็นไลบรารีเฉพาะสำหรับ Next.js รันคำสั่งนี้ใน CLI:

 yarn add @next/mdx

หรือสำหรับ npm:

 npm install @next/mdx

ยอดเยี่ยม! เราตั้งค่าเสร็จแล้ว มาทำให้มือของเราสกปรกและเขียนโค้ดที่มีความหมายกันเถอะ

การกำหนดค่าไฟล์ next.config.js

 const withMDX = require("@next/mdx")({ extension: /\.mdx?$/ }); module.exports = withMDX({ pageExtensions: ["js", "jsx", "md", "mdx"] });

ก่อนหน้านี้ในบทช่วยสอนนี้ ฉันบอกว่าไฟล์ในโฟลเดอร์ pages จะถือว่าเป็นเพจ/เส้นทางโดย Next.js ในเวลาบิลด์ ตามค่าเริ่มต้น Next.js จะเลือกไฟล์ที่มีนามสกุล . .js หรือ . .jsx นั่นเป็นเหตุผลที่เราต้องการไฟล์ปรับแต่ง เพื่อเพิ่มการปรับแต่งบางอย่างให้กับการทำงานเริ่มต้นของ Next.js

ไฟล์ next.config.js บอกเฟรมเวิร์กว่าไฟล์ที่มีนามสกุล . .md หรือ .mdx ควรได้รับการปฏิบัติเหมือนเป็นเพจ/เส้นทาง ณ เวลาที่สร้าง เนื่องจากโฟลเดอร์ blog ที่มีบทความอยู่ในไดเร็กทอรี pages

ดังที่กล่าวไปแล้ว เราสามารถเริ่มดึงข้อมูลโพสต์ในบล็อกได้ในส่วนถัดไป

กำลังดึงโพสต์บล็อก

สาเหตุหนึ่งที่ทำให้การสร้างบล็อกด้วย Next.js ทำได้ง่ายและไม่ซับซ้อนคือคุณไม่จำเป็นต้องใช้ GraphQL หรือสิ่งที่ชอบในการดึงข้อมูลโพสต์ในเครื่อง คุณสามารถใช้ JavaScript ปกติเพื่อรับข้อมูลได้

ใน getAllPosts.js :

 function importAll(r) { return r.keys().map((fileName) => ({ link: fileName.substr(1).replace(/\/index\.mdx$/, ""), module: r(fileName) })); } export const posts = importAll( require.context("./pages/blog/", true, /\.mdx$/) );

ไฟล์นี้สามารถข่มขู่ในตอนแรก เป็นฟังก์ชันที่นำเข้าไฟล์ MDX ทั้งหมดจากโฟลเดอร์ pages/blog และสำหรับแต่ละโพสต์ จะส่งคืนวัตถุที่มีเส้นทางของไฟล์ โดยไม่มีส่วนขยาย ( /post-1 ) และข้อมูลของโพสต์ในบล็อก

ด้วยเหตุนี้ เราจึงสามารถสร้างส่วนประกอบเพื่อจัดรูปแบบและแสดงข้อมูลในแอป Next.js ของเราได้

การสร้างส่วนประกอบ

ใน components/Layout.js :

 import Head from "next/head"; import Header from "./Header"; export default function Layout({ children, pageTitle, description }) { return ( <> <Head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta charSet="utf-8" /> <meta name="Description" content={description}></meta> <title>{pageTitle}</title> </Head> <main> <Header /> <div className="content">{children}</div> </main> </> ); }

ที่นี่ เรามีองค์ประกอบ Layout ซึ่งเราจะใช้เป็นเสื้อคลุมสำหรับบล็อก รับข้อมูลเมตาเพื่อแสดงในส่วนหัวของหน้าและองค์ประกอบที่จะแสดง

ใน components/Post.js :

 import Link from 'next/link' import { HeadPost } from './HeadPost' export const Post = ({ post }) => { const { link, module: { meta }, } = post return ( <article> <HeadPost meta={meta} /> <Link href={'/blog' + link}> <a>Read more →</a> </Link> </article> ) }

องค์ประกอบนี้มีหน้าที่แสดงตัวอย่างโพสต์ในบล็อก รับวัตถุ post เพื่อแสดงเป็นอุปกรณ์ประกอบฉาก ต่อไป เราใช้การทำลายล้างเพื่อดึง link ของโพสต์และ meta ที่จะแสดงออกจากวัตถุ ด้วยเหตุนี้ เราจึงสามารถส่งข้อมูลไปยังส่วนประกอบและจัดการการกำหนดเส้นทางด้วยองค์ประกอบ Link ได้

ใน components/BlogPost.js :

 import { HeadPost } from './HeadPost' export default function BlogPost({ children, meta}) { return ( <> <HeadPost meta={meta} isBlogPost /> <article>{children}</article> </> ) }

องค์ประกอบ BlogPost ช่วยให้เราสามารถแสดงบทความเดียว ได้รับโพสต์เพื่อแสดงและ meta ออบเจ็กต์

จนถึงตอนนี้ เราได้กล่าวถึงสิ่งต่างๆ มากมาย แต่เราไม่มีบทความที่จะแสดง มาแก้ไขกันในหัวข้อถัดไป

การเขียนโพสต์ด้วย MDX

 import BlogPost from '../../../components/BlogPost' export const meta = { title: 'Introduction to Next.js', description: 'Getting started with the Next framework', date: 'Aug 04, 2020', readTime: 2 } export default ({ children }) => <BlogPost meta={meta}>{children}</BlogPost>; ## My Headline Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque maximus pellentesque dolor non egestas. In sed tristique elit. Cras vehicula, nisl vel ultricies gravida, augue nibh laoreet arcu, et tincidunt augue dui non elit. Vestibulum semper posuere magna, quis molestie mauris faucibus ut.

อย่างที่คุณเห็น เรานำเข้าองค์ประกอบ BlogPost ซึ่งรับ meta และเนื้อหาของโพสต์

children พารามิเตอร์คือเนื้อหาของบล็อกโพสต์หรือทุกอย่างที่มาหลังจากวัตถุ meta เป็นหน้าที่รับผิดชอบในการแสดงผลโพสต์

ด้วยการเปลี่ยนแปลงดังกล่าว เราสามารถย้ายไปที่ไฟล์ index.js และแสดงโพสต์ในหน้าแรกได้

กำลังแสดงกระทู้

 import { Post } from "../components/Post"; import { posts } from "../getAllPosts"; export default function IndexPage() { return ( <> {posts.map((post) => ( <Post key={post.link} post={post} /> ))} </> ); }

ที่นี่ เราเริ่มต้นด้วยการนำเข้าองค์ประกอบ Post และบทความที่ดึงมาจากโฟลเดอร์ blog ต่อไป เราจะวนรอบอาร์เรย์ของบทความ และสำหรับแต่ละโพสต์ เราใช้องค์ประกอบ " Post " เพื่อแสดง เมื่อเสร็จแล้ว เราสามารถดึงข้อมูลโพสต์และแสดงบนเพจได้

เราเกือบจะเสร็จแล้ว อย่างไรก็ตาม องค์ประกอบ Layout ยังไม่ได้ใช้งาน เราสามารถใช้มันที่นี่และห่อส่วนประกอบของเราด้วย แต่นั่นจะไม่มีผลกับหน้าบทความ นั่นคือที่มาของไฟล์ _app.js ลองใช้สิ่งนั้นในหัวข้อถัดไป

การใช้ไฟล์ _app.js

ในที่นี้ สัญลักษณ์ขีดล่าง ( _ ) มีความสำคัญมาก หากคุณละเว้น Next.js จะถือว่าไฟล์นั้นเป็นเพจ/เส้นทาง

 import Layout from "../components/Layout"; export default function App({ Component, pageProps }) { return ( <Layout pageTitle="Blog" description="My Personal Blog"> <Component {...pageProps} /> </Layout> ); }

Next.js ใช้คอมโพเนนต์ App เพื่อเริ่มต้นหน้าเว็บ จุดประสงค์ของไฟล์นี้คือเพื่อลบล้างและเพิ่มสไตล์โกลบอลให้กับโปรเจ็กต์ หากคุณมีสไตล์หรือข้อมูลที่ต้องการแชร์ระหว่างโปรเจ็กต์ ให้ใส่ไว้ที่นี่

ขณะนี้เราสามารถเรียกดูโฟลเดอร์โครงการใน CLI และเรียกใช้คำสั่งต่อไปนี้เพื่อดูตัวอย่างบล็อกในเบราว์เซอร์:

 yarn dev

หรือใน npm:

 npm run dev

หากคุณเปิด https://localhost:3000 ในเบราว์เซอร์ คุณจะเห็นสิ่งนี้:

ดูตัวอย่างผลสุดท้าย

ยอดเยี่ยม! บล็อกของเราดูดี เราสร้างแอปบล็อกด้วย Next.js และ MDX เสร็จแล้ว

บทสรุป

ในบทช่วยสอนนี้ เราอธิบายเกี่ยวกับ Next.js โดยการสร้างบล็อกโดยใช้ไลบรารี MDX เฟรมเวิร์ก Next.js เป็นเครื่องมือแสนสะดวกที่ทำให้แอป React เป็นมิตรกับ SEO และรวดเร็ว สามารถใช้สร้างเว็บไซต์ JAMstack แบบคงที่และไดนามิกได้ในเวลาไม่นาน เพราะมันพร้อมสำหรับใช้งานจริงและมาพร้อมกับคุณสมบัติที่ดีบางอย่าง Next.js ถูกใช้อย่างแพร่หลายในบริษัทใหญ่ๆ และประสิทธิภาพของมันก็ยังดีขึ้นเรื่อยๆ เป็นสิ่งที่ควรตรวจสอบสำหรับโครงการต่อไปของคุณ

คุณสามารถดูตัวอย่างโครงการที่เสร็จแล้วใน CodeSandbox

ขอบคุณที่อ่าน!

ทรัพยากร

แหล่งข้อมูลที่มีประโยชน์เหล่านี้จะนำคุณไปไกลกว่าขอบเขตของบทช่วยสอนนี้

  • เอกสาร Next.js
  • เอกสาร Next.js และ MDX
  • “สร้างแอป Next.js”, Next.js