Skip to content

Next.js 基础:从安装到部署 GitHub Pages

Next.js 是一个流行的 React 框架,以其服务器端渲染(SSR)、静态站点生成(SSG)、基于文件的路由系统和优化的性能而闻名。本教程旨在引导开发者完成 Next.js 的基本使用流程,从项目初始化、页面和组件的创建,到最终将应用编译为静态文件并部署到 GitHub Pages。这对于希望构建高性能静态网站或利用 GitHub Pages 进行免费托管的开发者尤其有用。

环境准备与项目初始化

在开始之前,请确保本地开发环境已安装 Node.js (建议使用 LTS 版本) 和 npm (或 yarn/pnpm)。本教程假设项目将在一个名为 web-develop 的现有目录下进行。

首先,通过命令行终端进入 web-develop 目录。然后,使用 create-next-app 脚手架工具来创建一个新的 Next.js 项目。执行以下命令,将 my-next-app 替换为您希望的项目名称:

Terminal window
cd web-develop
npx create-next-app@latest my-next-app

安装过程中,脚手架会询问一些配置选项(例如是否使用 TypeScript, ESLint, Tailwind CSS, src/ 目录, App Router 等)。为了保持教程简洁,可以选择默认选项或根据个人偏好选择。本教程将基于使用 App Router(默认推荐)进行说明。

安装完成后,进入新创建的项目目录:

Terminal window
cd my-next-app

本地预览

在开发过程中,需要实时查看更改的效果。Next.js 提供了一个开发服务器来实现此功能。在项目根目录下运行以下命令:

Terminal window
npm run dev
# 或者 yarn dev / pnpm dev

该命令会启动一个本地开发服务器,通常监听在 http://localhost:3000。在浏览器中打开这个地址,就可以看到正在开发的 Next.js 应用。对代码进行的任何修改,通常都会自动热重载,无需手动刷新页面。访问 http://localhost:3000/about 可以查看之前创建的“关于”页面。

创建示例页面

Next.js 使用基于文件系统的路由。在 App Router 模式下,页面在 app 目录下定义。每个路由段对应一个文件夹,而页面 UI 则在 page.js (或 .jsx, .tsx) 文件中定义。

例如,创建一个“关于”页面。在 app 目录下创建一个名为 about 的新文件夹,然后在 about 文件夹内创建一个 page.js 文件:

Terminal window
mkdir app/about
touch app/about/page.js

编辑 app/about/page.js 文件,添加以下简单的 React 组件代码:

app/about/page.js
export default function AboutPage() {
return (
<div>
<h1>关于我们</h1>
<p>这是一个使用 Next.js 创建的示例“关于”页面。</p>
</div>
);
}

现在,当应用运行时,访问 /about 路径即可看到这个页面。

创建示例组件

组件化是现代前端开发的核心思想,它有助于代码复用和维护。通常,可复用的组件会放在一个单独的目录中,例如 components

首先,在项目根目录下创建 components 目录(如果脚手架未自动创建):

Terminal window
mkdir components

接着,在 components 目录下创建一个名为 Greeting.js 的组件文件:

Terminal window
touch components/Greeting.js

编辑 components/Greeting.js 文件,添加以下代码:

components/Greeting.js
export default function Greeting({ name }) {
return (
<p>你好, <span v-pre>{{ name }}</span>! 欢迎来到 Next.js 的世界。</p>
);
}

这个组件接收一个 name 属性并显示问候语。注意这里使用了 {{ name }},需要用 <span> 包裹以防止被误解析。

现在,可以在页面中导入并使用这个组件。例如,修改首页 app/page.js 来使用 Greeting 组件:

app/page.js
import Greeting from '../components/Greeting'; // 调整导入路径
export default function HomePage() {
return (
<div>
<h1>欢迎来到我的 Next.js 应用</h1>
<Greeting name="访客" />
{/* 你可以传递不同的 name */}
<Greeting name="开发者" />
</div>
);
}

编译为静态站点 (SSG)

对于不需要服务器端动态渲染内容的场景,可以将 Next.js 应用导出为纯静态 HTML、CSS 和 JavaScript 文件。这对于部署到 GitHub Pages 等静态托管平台非常理想。

首先,需要配置 Next.js 以启用静态导出模式。打开项目根目录下的 next.config.js 文件(如果不存在则创建它),并添加 output: 'export' 配置:

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
// 注意:如果部署到 GitHub Pages 的子目录(非根域名),
// 例如 https://<username>.github.io/<repo-name>/
// 需要设置 basePath 和 assetPrefix。
// basePath: process.env.NODE_ENV === 'production' ? '/<repo-name>' : undefined,
// assetPrefix: process.env.NODE_ENV === 'production' ? '/<repo-name>/' : undefined,
// 将 <repo-name> 替换为你的 GitHub 仓库名称。
// 确保在构建生产版本时设置 basePath 和 assetPrefix。
// 例如,在 package.json 的 build 脚本中设置环境变量,
// 或者使用 Vercel 等平台的自动配置。
// 如果部署到根域名 (<username>.github.io),则无需设置 basePath 和 assetPrefix。
// 如果图片使用了 next/image 优化,静态导出时可能需要禁用它或配置加载器
images: {
unoptimized: true, // 对于静态导出,通常需要禁用 Image Optimization
},
};
module.exports = nextConfig;

请特别注意上述关于 basePathassetPrefix 的注释。如果您的 GitHub Pages 站点地址是 https://<username>.github.io/<repo-name>/ 形式(即项目部署在子目录下),则必须取消注释并正确设置 basePathassetPrefix/<repo-name>。如果站点是 https://<username>.github.io/(即仓库名为 <username>.github.io),则无需配置。同时,对于静态导出,通常需要禁用 Next.js 的图像优化 (images: { unoptimized: true }),因为静态托管环境不支持 Next.js 的图像优化服务器。

配置完成后,运行构建命令:

Terminal window
npm run build
# 或者 yarn build / pnpm build

此命令会执行 next build。由于设置了 output: 'export',Next.js 会自动将应用构建并导出为静态文件。这些文件默认会生成在项目根目录下的 out 文件夹中。

用户的要求是将编译结果输出到 docs 目录。由于 output: 'export' 模式固定输出到 out 目录,需要在构建后手动或通过脚本将 out 目录的内容移动或重命名为 docs。可以修改 package.json 中的 build 脚本来实现自动化:

// package.json (示例片段)
{
"scripts": {
"dev": "next dev",
"build": "next build && rm -rf docs && mv out docs", // 先删除旧的 docs (如果存在),然后将 out 重命名为 docs
"start": "next start",
"lint": "next lint"
}
}

注意:rm -rf docs && mv out docs 命令在 Linux/macOS 下有效。Windows 用户可能需要使用等效命令,如 rd /s /q docs && ren out docs (需要测试兼容性) 或使用跨平台的工具如 rimrafmv (通过 npm install -g rimrafnpm install -g move-cli 安装)。

现在再次运行 npm run build,静态文件就会被生成并放置在 docs 目录中。

部署到 GitHub Pages

最后一步是将编译好的静态站点部署到 GitHub Pages。

  1. 创建 .nojekyll 文件:GitHub Pages 默认使用 Jekyll 处理站点。为了防止它忽略以下划线开头的文件夹(如 Next.js 生成的 _next 目录),需要在 docs 目录的根部创建一个空的 .nojekyll 文件。

    Terminal window
    touch docs/.nojekyll
  2. 初始化 Git 并提交代码:如果项目尚未进行版本控制,需要初始化 Git 仓库,并将所有项目文件(包括 docs 目录)添加到仓库并提交。

    Terminal window
    git init
    git add .
    git commit -m "Initial commit with Next.js app and static build"
  3. 创建 GitHub 仓库:在 GitHub 上创建一个新的空仓库。

  4. 关联远程仓库并推送:将本地仓库与 GitHub 远程仓库关联,并将代码推送到 GitHub。将 <your-github-repo-url> 替换为实际的仓库 URL。

    Terminal window
    git remote add origin <your-github-repo-url>
    git branch -M main # 或者 master,取决于你的默认分支名
    git push -u origin main
  5. 配置 GitHub Pages

    • 在 GitHub 仓库页面,点击 “Settings” (设置)。
    • 在左侧导航栏中选择 “Pages”。
    • 在 “Build and deployment” 部分:
      • 选择 “Source” 为 “Deploy from a branch”。
      • 选择部署的 “Branch” 为 main (或你推送代码的分支)。
      • 选择文件夹为 /docs
    • 点击 “Save”。

GitHub Actions 会开始构建和部署过程(如果配置了 Actions)或者直接从指定分支和目录部署(如果选择 Deploy from a branch)。稍等片刻,你的 Next.js 静态站点应该就可以通过 GitHub Pages 提供的 URL 访问了。URL 通常是 https://<username>.github.io/<repo-name>/https://<username>.github.io/ (如果仓库名为 <username>.github.io)。

以下 Mermaid 图示概括了从开发到部署的主要流程:

graph LR
A["1. 本地开发 (代码编写)"] --> B{"2. 运行 `npm run dev`"};
B --> C["3. 本地预览 (localhost)"];
A --> D{"4. 配置 `next.config.js` (output: 'export', basePath, assetPrefix?, images.unoptimized)"};
D --> E{"5. 修改 `package.json` build 脚本 (输出到 docs)"};
E --> F{"6. 运行 `npm run build`"};
F --> G["7. 生成静态文件到 `docs` 目录"];
G --> H{"8. 添加 `docs/.nojekyll` 文件"};
H --> I{"9. Git 提交并推送到 GitHub"};
I --> J{"10. 配置 GitHub Pages (Source: /docs)"};
J --> K["11. 部署完成,在线访问"];

小结

本教程介绍了使用 Next.js 创建应用、添加页面和组件、进行本地预览的基本流程。重点讲解了如何将 Next.js 应用配置并编译为静态文件,以及如何通过修改构建脚本将输出定向到 docs 目录。最后,详细说明了将生成的静态站点部署到 GitHub Pages 的步骤,包括必要的 basePathassetPrefix 配置和 .nojekyll 文件的添加。遵循这些步骤,开发者可以轻松地利用 Next.js 的强大功能构建静态网站,并借助 GitHub Pages 实现免费托管和发布。

参考资料