Next.js 如何实现 SSG 静态网站

前言

在现代前端开发领域,Next.js 是一个极其流行的 React 框架,它以易用性、灵活性和高性能而闻名。其核心功能之一就是静态站点生成(Static Site Generation,简称 SSG)。SSG 允许你在构建时生成静态的 HTML 文件,这些文件可以被缓存并直接提供给用户,从而提供极快的加载速度。

SSG 是什么

SSG 是一种预渲染技术,它在构建过程中生成完整的静态 HTML 页面。与传统的动态服务器端渲染(SSR)相比,SSG 页面无需等待服务器处理,可以直接从 CDN 缓存中提供,极大地提升了访问速度和性能。

SSG 的优势与缺点

优势:

  1. 性能:静态文件可被全球 CDN 缓存,提供快速加载体验。
  2. 可靠性:静态文件比动态服务器更可靠,减少了服务器运行时错误的可能。
  3. 成本:减少了服务器计算资源的需求,可以降低托管成本。
  4. 安全性:静态页面减少了安全漏洞的风险。
  5. SEO 友好:静态页面便于搜索引擎爬虫索引,有助于提升 SEO。

缺点:

  1. 实时性:内容更新需要重新构建和部署,不适合频繁变动的内容。
  2. 构建时间:对于大型站点,构建过程可能变得较慢。
  3. 灵活性有限:静态页面难以实现复杂的动态交互。

在 Next.js 中实现 SSG

接下来,让我们通过一个简单的例子来展示如何在 Next.js 中实现 SSG。

一、创建 Next.js 应用

首先确保你已安装了 Node.js 环境。然后在命令行中运行以下命令来创建一个新的 Next.js 应用:

sh
npx create-next-app my-static-site cd my-static-site

二、创建静态页面

pages 目录下创建一个新的页面文件 about.js

js
// pages/about.js export default function About() { return ( <div> <h1>About Us</h1> <p>Welcome to our static about page!</p> </div> ); }

此文件导出了一个 React 组件,Next.js 将会在构建时自动将其生成为静态页面。

三、使用 getStaticProps 获取数据

如果你的页面需要外部数据,可以使用 getStaticProps 来提供数据。Next.js 将在构建时调用它,并将返回的数据作为 props 传递给页面。

创建 posts.js 文件来展示一个带有博客文章列表的页面:

js
// pages/posts.js // 假设我们有一个用来获取文章的异步函数 import { getPosts } from '../lib/posts'; export async function getStaticProps() { const posts = await getPosts(); return { props: { posts, }, }; } export default function Posts({ posts }) { return ( <div> <h1>Blog Posts</h1> <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); }

这段代码中的 getPosts 函数用于从后端或文件系统中获取文章数据。

四、构建和部署

通过以下命令来,构建你的 Next.js 应用:

sh
npm run build

这个命令会触发 Next.js 的构建过程,在这个过程中会生成静态页面。这些页面包括了我们之前创建的 about.jsposts.js

构建完成后,Next.js 会输出构建的结果,其中包括了每个页面的静态文件生成情况。

最后,你可以使用以下命令来启动一个生产模式的服务器,这样就可以在本地测试构建好的静态页面了:

sh
npm start

然而,在实际的生产环境中,你会希望部署到一个静态网站托管服务上,比如 Vercel(Next.js 的官方云平台),Netlify 或者其他支持静态内容托管的服务。

如果你决定使用 Vercel,部署过程非常简单。首先安装 Vercel CLI:

sh
npm i -g vercel

然后,在项目根目录下运行 vercel 命令来部署你的静态网站:

sh
vercel

Vercel 会自动为你的项目创建并配置一个新的部署,你的静态站点会被部署到一个全球分布的 CDN 上。每次你推送代码变动到主分支,Vercel 都会自动重新构建并部署你的静态站点。

进阶用法

静态生成的路径参数

如果你的页面路径依赖于外部数据(例如显示单个博客帖子的页面),那么你还需要使用 getStaticPaths 函数来定义哪些路径将被静态生成。

以下是一个如何使用 getStaticPaths 以及 getStaticProps 来为每篇博客文章生成静态页面的例子:

js
// pages/posts/[id].js import { getPostIds, getPostData } from '../lib/posts'; export async function getStaticPaths() { const paths = await getPostIds(); return { paths, fallback: false // 如果未匹配到路径,则显示404页面 }; } export async function getStaticProps({ params }) { const postData = await getPostData(params.id); return { props: { postData, }, }; } export default function Post({ postData }) { return ( <article> <h1>{postData.title}</h1> <div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} /> </article> ); }

在这个例子中,getPostIds 函数负责返回一个包含所有有效博客帖子 ID 的数组,而 getPostData 函数则根据 ID 获取每篇文章的数据。

总结

通过使用 Next.js 的 SSG 功能,你可以轻松创建快速、高效、安全的静态网站。尽管它有一些缺点,例如对实时数据的支持较差,以及可能较长的构建时间,但其优势通常会大于这些缺点,特别是对于内容较为固定的网站。

通过结合使用 getStaticPropsgetStaticPaths,你可以为几乎任何类型的数据生成静态页面,为用户提供无与伦比的访问体验。