GitHub Pages 技术文档站点搭建实践指南

GitHub Pages 技术文档站点搭建实践指南

1. 开发者的实际需求

作为开发者,我们经常需要将技术笔记、项目文档或学习成果以网站形式对外展示。这种展示方式相比简单的代码仓库浏览具有明显优势,包括统一的导航结构、专业的视觉呈现、便捷的搜索功能以及更好的阅读体验。本文将详细介绍如何使用 MkDocs 和 GitHub Pages 构建这样一个技术文档网站,特别是如何正确处理 Jupyter Notebook 文件的展示。例如:https://gritjw.github.io/hot_100/

2. 两种展示方式的本质区别

在 GitHub 上展示内容有两种截然不同的方式,理解它们的区别是后续工作的基础。

第一种是直接利用 GitHub 仓库的文件预览功能。当你将 Markdown 文件或 Jupyter Notebook 文件推送到仓库后,GitHub 会自动渲染这些文件的内容。访问者可以在仓库界面点击文件名查看格式化后的内容,包括代码、文本、数学公式和图表输出。这种方式无需任何配置,但本质上仍然是文件浏览而非网站体验。访问者看到的是仓库的目录树结构,缺少统一的首页、导航菜单和主题样式。

第二种是使用静态站点生成器构建完整的网站,通过 GitHub Pages 托管。这种方式下,访问者访问的是一个具有完整网站特征的页面,拥有自定义的首页、侧边栏导航、全文搜索和统一的视觉风格。但 GitHub Pages 本身只是一个静态文件托管服务,它不会自动将你的 Markdown 或 Notebook 文件转换成网页。要实现这种展示效果,必须先使用 MkDocs、Jupyter Book 或 Sphinx 等工具将源文件构建成 HTML 页面,然后再部署到 GitHub Pages。

两种方式的选择取决于具体需求。如果只是快速分享几个笔记文件,且不需要精心组织的结构,第一种方式完全足够。但如果目标是构建一个专业的文档站点,为读者提供良好的浏览体验,或者需要长期维护一个知识库,那么投入时间搭建 MkDocs 站点是值得的。

3. MkDocs 完整搭建流程

以下是从零开始搭建支持 Jupyter Notebook 的 MkDocs 文档站点的完整流程。

3.1 环境准备

首先确保系统已安装 Python 3.7 或更高版本。然后安装必要的依赖包,包括 MkDocs 核心库、Material 主题和 Jupyter 支持插件。

bash 复制代码
pip install mkdocs mkdocs-material mkdocs-jupyter

Material 主题是目前最流行的 MkDocs 主题之一,提供了现代化的界面设计和丰富的自定义选项。mkdocs-jupyter 插件则使 MkDocs 能够将 Jupyter Notebook 文件转换为网页。

3.2 项目结构初始化

在本地克隆或创建 GitHub 仓库后,建立以下目录结构。

复制代码
my-tech-notes/
├── mkdocs.yml
├── docs/
│   ├── index.md
│   ├── notebooks/
│   │   ├── algorithm.ipynb
│   │   └── data_analysis.ipynb
│   └── images/
│       └── diagram.png
└── .gitignore

所有文档源文件统一放在 docs 目录下。index.md 将作为网站首页,notebooks 子目录存放 Jupyter Notebook 文件,images 目录存放图片资源。这种组织方式便于后续管理和扩展。

3.3 配置文件编写

在项目根目录创建 mkdocs.yml 配置文件,这是 MkDocs 的核心配置。以下是一个完整的配置示例。

yaml 复制代码
site_name: 我的技术文档
site_url: https://username.github.io/repo-name/
site_description: 算法与数据分析学习笔记
site_author: Your Name

theme:
  name: material
  language: zh
  palette:
    - scheme: default
      primary: indigo
      toggle:
        icon: material/brightness-7
        name: 切换至深色模式
    - scheme: slate
      primary: indigo
      toggle:
        icon: material/brightness-4
        name: 切换至浅色模式
  features:
    - navigation.tabs
    - navigation.sections
    - navigation.top
    - search.highlight
    - search.share
    - search.suggest

plugins:
  - search:
      lang:
        - zh
        - en
  - mkdocs-jupyter:
      include_source: true
      execute: false
      allow_errors: false

nav:
  - 首页: index.md
  - 算法笔记:
      - 双指针: notebooks/two_pointers.ipynb
      - 动态规划: notebooks/dynamic_programming.ipynb
  - 数据分析:
      - Pandas 基础: notebooks/pandas_basics.ipynb

markdown_extensions:
  - pymdownx.highlight:
      anchor_linenums: true
  - pymdownx.superfences
  - pymdownx.arithmatex:
      generic: true

extra_javascript:
  - https://polyfill.io/v3/polyfill.min.js?features=es6
  - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js

配置中有几个关键参数需要说明。site_url 必须设置为正确的 GitHub Pages 地址,格式为 https://用户名.github.io/仓库名/。theme 部分配置了 Material 主题的外观和功能特性,包括深浅色模式切换和导航增强功能。

plugins 部分的 mkdocs-jupyter 插件配置尤为重要。execute 参数设置为 false 表示在构建网站时不执行 Notebook 中的代码,而是直接使用 Notebook 文件中已保存的输出。这样可以避免构建时间过长,也避免了在 CI 环境中可能遇到的依赖问题。include_source 设置为 true 则会在生成的网页中包含源代码的下载链接。

nav 部分定义了网站的导航结构。你可以直接在这里引用 .ipynb 文件,mkdocs-jupyter 插件会自动处理转换。markdown_extensions 和 extra_javascript 部分则启用了代码高亮和数学公式渲染支持,这对技术文档尤为重要。

3.4 首页内容准备

在 docs/index.md 中编写网站首页内容,这将是访问者看到的第一个页面。

markdown 复制代码
# 欢迎来到我的技术笔记

本站记录了我在算法学习和数据分析过程中的笔记和思考。

## 主要内容

本站包含以下主题的技术笔记:

- **算法专题**:包括双指针、动态规划等经典算法的分析与实现
- **数据分析**:使用 Python 进行数据处理和可视化的实践经验

## 快速开始

建议从左侧导航栏选择感兴趣的主题开始阅读。每篇笔记都包含详细的代码示例和解释说明。

3.5 本地预览测试

在项目根目录运行以下命令启动本地开发服务器。

bash 复制代码
mkdocs serve

该命令会在本地 8000 端口启动一个实时预览服务器。在浏览器访问 http://127.0.0.1:8000 即可查看网站效果。当你修改 docs 目录下的任何文件或 mkdocs.yml 配置时,浏览器会自动刷新显示最新内容。这个实时预览功能使得文档编写和调试变得非常高效。

在预览过程中,重点检查以下几个方面。首先确认 Notebook 文件是否正确渲染,包括代码块、输出结果和图表。其次检查导航菜单是否符合预期,所有链接是否有效。如果使用了数学公式,需要确认 MathJax 是否正常加载和渲染。发现问题时可以实时修改配置文件或源文件,直到达到满意的效果。

3.6 部署到 GitHub Pages

确认本地预览效果无误后,执行部署命令。

bash 复制代码
python -m mkdocs gh-deploy --clean

这个命令会自动完成构建和部署的全过程。具体来说,MkDocs 首先会读取 mkdocs.yml 配置和 docs 目录下的所有源文件,将它们编译成静态 HTML 页面,生成到临时的 site 目录中。然后使用 ghp-import 工具将 site 目录的内容推送到仓库的 gh-pages 分支。--clean 参数确保在构建前清理旧的临时文件。

部署完成后,访问 GitHub 仓库的 Settings 页面,在 Pages 部分确认 Source 设置为 gh-pages 分支。通常这个设置会自动完成,但首次部署时最好手动检查一下。GitHub Pages 的更新可能需要几分钟时间才能生效,之后就可以通过 https://用户名.github.io/仓库名/ 访问网站了

4. 两个分支的职责分离

理解 MkDocs 工作流程的关键在于认识到 main 分支和 gh-pages 分支有着完全不同的职责。

main 分支存储的是文档的源文件,包括 Jupyter Notebook 文件、Markdown 文件、图片资源以及 mkdocs.yml 配置文件。这些是人类可读和可编辑的内容,是文档的真正来源。当你修改笔记内容、添加新的文档或调整网站配置时,都是在 main 分支上进行操作并提交。

gh-pages 分支则完全不同,它存储的是机器生成的静态网页文件,包括 HTML、CSS 和 JavaScript 文件。这些文件是 MkDocs 根据 main 分支的源文件自动构建生成的,供浏览器访问使用。访问者通过 GitHub Pages 看到的网站内容就来自这个分支。

这种设计的核心理念是将源代码和构建产物严格分离。如果将两者混合在同一分支,Git 的提交历史中就会充斥着大量自动生成的 HTML 代码变更,使得代码审查变得困难,也会让版本历史变得混乱。通过分离两个分支,main 分支的历史保持清晰,只记录文档内容的实质性变更,而 gh-pages 分支完全由自动化工具管理,不需要人工干预。

当你执行 mkdocs gh-deploy 命令时,它只会操作 gh-pages 分支,不会也不应该触碰 main 分支。这不是 bug,而是刻意的设计选择。理解这一点,就能明白为什么文档更新需要两个独立的步骤,一个是提交源文件到 main 分支,另一个是发布构建产物到 gh-pages 分支。

5. 日常维护工作流程

在完成初始搭建后,日常更新文档的流程变得非常规范。每次需要更新内容时,按照以下步骤操作即可。

bash 复制代码
# 步骤 1:切换到 main 分支并拉取最新代码
git checkout main
git pull origin main

# 步骤 2:修改或新增文档内容
# 在 docs/notebooks/ 目录下编辑 .ipynb 文件
# 或在 docs/ 目录下编辑 .md 文件
# 如果添加了新文件,记得更新 mkdocs.yml 中的 nav 配置

# 步骤 3:本地预览确认效果
mkdocs serve
# 在浏览器中检查修改是否正确,按 Ctrl+C 停止服务器

# 步骤 4:提交源文件到 main 分支
git add .
git commit -m "更新算法笔记内容"
git push origin main

# 步骤 5:构建并发布网站到 gh-pages 分支
python -m mkdocs gh-deploy --clean

这五个步骤构成了完整的更新循环。步骤 1 到 3 是准备和验证阶段,确保你的修改是正确的。步骤 4 将源文件的变更推送到 GitHub 仓库,完成版本控制。步骤 5 则将更新后的内容构建成网站并发布。

需要强调的是,步骤 4 和步骤 5 虽然通常连续执行,但它们在概念上是完全独立的。git push origin main 是在保存你的工作成果到源代码仓库,而 mkdocs gh-deploy 是在发布网站到公开访问的地址。前者操作 main 分支,后者操作 gh-pages 分支,两者互不干扰。

如果团队协作或希望进一步自动化流程,可以配置 GitHub Actions 工作流,在每次推送到 main 分支时自动触发 MkDocs 构建和部署。这样就可以省略手动执行步骤 5 的操作,实现完全自动化的发布流程。

6. 总结与建议

通过 MkDocs 和 GitHub Pages 搭建技术文档站点是一个一次性投入、长期受益的过程。虽然初始配置需要理解一些概念和工具,但一旦建立起标准化的工作流程,后续的维护成本很低,而带来的专业性和可用性提升是显著的。

核心要点在于理解源文件和构建产物的分离原则。main 分支管理可编辑的源内容,gh-pages 分支托管生成的网站文件,两者各司其职。日常工作中只需要关注 main 分支的内容更新,构建和部署由 MkDocs 自动处理。

对于刚开始使用这套系统的开发者,建议先用简单的测试内容完整走通一遍流程,熟悉每个步骤的作用。在实际使用过程中,可以根据需要逐步调整主题配置、添加插件功能或优化导航结构。MkDocs 的生态系统非常丰富,有大量插件可以扩展功能,包括支持更多文档格式、增强搜索能力或添加评论系统等。

最后需要提醒的是,Notebook 文件在提交前最好保留必要的输出结果,因为 MkDocs 默认不会重新执行代码。如果某些输出文件过大导致 Git 仓库体积增长过快,可以考虑使用 Git LFS 管理大文件,或者在 CI 环境中配置代码执行并缓存输出结果。这些优化可以在基础流程稳定后逐步实施。