建立簡單的部落格架構

我們範例中的部落格文章將會儲存為應用程式目錄中的本地 markdown 檔案(而非從外部資料來源獲取),因此我們需要從檔案系統讀取資料。

在本節中,我們將逐步建立一個從檔案系統讀取 markdown 資料的部落格。

建立 markdown 檔案

首先,在根目錄中建立一個名為 posts 的新頂層目錄(這與 pages/posts 不同)。在 posts 目錄內,建立兩個檔案:pre-rendering.mdssg-ssr.md

現在,將以下程式碼複製到 posts/pre-rendering.md

---
title: 'Two Forms of Pre-rendering'
date: '2020-01-01'
---
 
Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. The difference is in **when** it generates the HTML for a page.
 
- **Static Generation** is the pre-rendering method that generates the HTML at **build time**. The pre-rendered HTML is then _reused_ on each request.
- **Server-side Rendering** is the pre-rendering method that generates the HTML on **each request**.
 
Importantly, Next.js lets you **choose** which pre-rendering form to use for each page. You can create a "hybrid" Next.js app by using Static Generation for most pages and using Server-side Rendering for others.

接著,將以下程式碼複製到 posts/ssg-ssr.md

---
title: 'When to Use Static Generation v.s. Server-side Rendering'
date: '2020-01-02'
---
 
We recommend using **Static Generation** (with and without data) whenever possible because your page can be built once and served by CDN, which makes it much faster than having a server render the page on every request.
 
You can use Static Generation for many types of pages, including:
 
- Marketing pages
- Blog posts
- E-commerce product listings
- Help and documentation
 
You should ask yourself: "Can I pre-render this page **ahead** of a user's request?" If the answer is yes, then you should choose Static Generation.
 
On the other hand, Static Generation is **not** a good idea if you cannot pre-render a page ahead of a user's request. Maybe your page shows frequently updated data, and the page content changes on every request.
 
In that case, you can use **Server-Side Rendering**. It will be slower, but the pre-rendered page will always be up-to-date. Or you can skip pre-rendering and use client-side JavaScript to populate data.

你可能已經注意到,每個 markdown 檔案頂部都有一個包含 titledate 的中繼資料區塊。這稱為 YAML Front Matter,可以使用名為 gray-matter 的函式庫來解析。

安裝 gray-matter

首先安裝 gray-matter,它讓我們能夠解析每個 markdown 檔案中的中繼資料。

npm install gray-matter

建立讀取檔案系統的公用函式

接下來,我們將建立一個用於從檔案系統解析資料的公用函式。透過這個公用函式,我們希望達成以下目標:

  • 解析每個 markdown 檔案並獲取 titledate 和檔案名稱(將用作文章 URL 的 id)。
  • 在首頁上列出按日期排序的資料。

在根目錄中建立一個名為 lib 的頂層目錄。然後,在 lib 目錄內建立一個名為 posts.js 的檔案,並複製貼上以下程式碼:

import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
 
const postsDirectory = path.join(process.cwd(), 'posts');
 
export function getSortedPostsData() {
  // Get file names under /posts
  const fileNames = fs.readdirSync(postsDirectory);
  const allPostsData = fileNames.map((fileName) => {
    // Remove ".md" from file name to get id
    const id = fileName.replace(/\.md$/, '');
 
    // Read markdown file as string
    const fullPath = path.join(postsDirectory, fileName);
    const fileContents = fs.readFileSync(fullPath, 'utf8');
 
    // Use gray-matter to parse the post metadata section
    const matterResult = matter(fileContents);
 
    // Combine the data with the id
    return {
      id,
      ...matterResult.data,
    };
  });
  // Sort posts by date
  return allPostsData.sort((a, b) => {
    if (a.date < b.date) {
      return 1;
    } else {
      return -1;
    }
  });
}

注意:

你不需要理解上述程式碼的運作原理來學習 Next.js,這個函式的目的是讓部落格範例能夠運作。但如果你想了解更多:

  • fs 是一個 Node.js 模組,可讓你從檔案系統讀取檔案。
  • path 是一個 Node.js 模組,可讓你操作檔案路徑。
  • matter 是一個函式庫,可讓你解析每個 markdown 檔案中的中繼資料。
  • 在 Next.js 中,lib 資料夾不像 pages 資料夾有特定的命名規則,因此你可以隨意命名。通常慣例是使用 libutils

獲取部落格資料

現在部落格資料已經解析完成,我們需要將其添加到首頁(pages/index.js)。我們可以使用 Next.js 的資料獲取方法 getStaticProps() 來實現。在下一節中,我們將學習如何實作 getStaticProps()

首頁

讓我們在下一頁繼續!

On this page