简介:这份资源为个人开发者qianhongbo的网站源码包,站点基于Hexo框架构建,使用Stylus作为CSS预处理器编写自定义主题,并部署于GitHub Pages。对于想学习静态博客搭建、研究Hexo目录结构或深入理解Stylus样式的Web开发者与博客爱好者而言,是一份难得的真实项目案例。压缩包约2.57MB,内含完整Hexo项目文件夹,包括站点全局配置、主题Stylus源文件、Markdown文章模板、页面布局以及图片脚本等静态资源;尽管当前未列出具体文件个数,但目录层级清晰,完全符合Hexo标准组织方式,便于逐项研读。目前已有68人学习浏览,适合计划从零打造个人博客的用户快速建立全局认识。通过分析这份资源,读者能掌握Hexo写作与编译流程、GitHub Pages部署和域名绑定方法,并直观看到Stylus变量、嵌套、混合宏等特性在真实主题中的应用;同时还可借鉴作者在导航分类、标签页、响应式排版上的设计思路,用以优化自己的博客或作品集,省去大量从零摸索的时间。 "qianhongbo.github.io" 是我的个人网站地址,仔细看这个域名后缀,就知道它是托管在 GitHub Pages 上的。这篇博文不是要写一份从零开始的官方教程,而是想把我从搭建个人网站、中途换技术栈、到长期稳定维护的完整经历复盘一遍:为什么最终选择 GitHub Pages、仓库命名有哪些容易忽略的规则、静态站点生成器怎么选、部署上线后真实遇到过的几个问题、以及自定义域名和评论统计这些"锦上添花"的功能到底怎么接。无论你是准备搭个人博客、作品集,还是单纯想维护一个名片页,我的这些实践经验应该能帮你节约不少时间,也能让你少踩几个我踩过的坑。
1. 为什么我最后选择了 GitHub Pages —— 个人站托管方案对比
1.1 我认真对比过的几条路线
决定做个人网站之后,第一件事不是选框架,而是选托管方式。市面上主流方案无非是云服务器、虚拟主机、对象存储加 CDN,以及静态托管平台。我每条路都认真试过,感受完全不同。
云服务器是最先考虑的,毕竟最灵活。那时候研究了一阵子轻量服务器,发现一年几百块的成本其实还能接受。但真把这个方案拆开看,问题全在运维上:要自己装 Nginx、配 HTTPS 证书、做好安全组规则,遇到恶意扫描和攻击还得处理。对一个只想安安静静写博客的人来说,花在环境维护上的精力很容易超过内容创作本身。除非你想顺便跑一些完整的 Web 应用或者 API 服务,否则只为个人网站买一台云服务器,性价比属实不高。
虚拟主机我也了解过,早年建站常用它,价格便宜、带控制面板。但问题在于它主要面向 PHP 环境,对静态站点反而不够友好。而且访问速度和稳定性受服务商影响很大,有些便宜主机甚至没有可靠的日志查看方式,出了问题想排查都无从下手。说白了,虚拟主机是当年没得选的情况下的产物,现在做静态个人站,我不太推荐再去走这条路。
对象存储加 CDN 的方案我试用过几天。静态文件丢进存储桶,配上 CDN 加速,个人小站一个月的流量费用可以低到忽略不计。可它最大的短板是没有任何版本管理的概念,每次更新文章都得手动上传覆盖文件,更新频率稍微一高就变得非常痛苦。你没法方便地回滚、没法对比历史版本,文件一多还容易在本地和线上之间产生不一致。
相比之下,GitHub Pages 的优势几乎是专门为个人网站准备的:免费额度对个人站来说足够用,文件以 Git 仓库的形式管理,天然带版本历史和回滚能力,写作和发布就是一次 git commit 的功夫,还自动配置 HTTPS。对一个常年和代码打交道的技术人来说,这套流程理解和上手几乎零成本。
1.2 除了免费,我更看重这三点
很多介绍 GitHub Pages 的文章都把"免费"放在最前面,免费当然很重要,但真正让我确定长期使用它的,是后面这三件事。
第一是版本管理带来的安全感。文章和代码一样,有了提交历史之后,改错了随时都能退回去。我以前也写过博客,最怕的就是改版时把以前写得还不错的内容改坏了,又没有备份机制。Git 解决的不只是文件备份问题,更是给了你随意尝试的底气。
第二是 Markdown 写作体验。技术类内容的写作,Markdown 是效率最高的格式之一。GitHub Pages 配合静态站点生成器对 Markdown 的支持非常成熟,本地编辑器里写完,推上去就是一个排版整齐的页面。传统博客后台那种富文本编辑器,复制代码块、调整格式都得折腾半天,两种体验差距很大。
第三是 HTTPS 的默认支持。早些年个人网站几乎没有加密,很多浏览器还会直接提示不安全。GitHub Pages 现在对自定义域名也支持自动签发和续期 HTTPS 证书,这个门槛被直接抹平了。你不需要懂证书申请流程,只要在设置里把自定义域名填进去,剩下交给它处理。
综合这些因素,我才最终确定了以 GitHub Pages 作为个人站点的主阵地。它不是一个性能最强、功能最全的方案,但对"个人网站"这个场景来说,它把免费、版本管理、写作体验和发布流程整合得非常顺。
2. 仓库命名与发布机制:一个仓库名决定你的域名
2.1 被很多人忽视的命名规则
GitHub Pages 的个人站点有一个硬性规则:仓库名必须严格等于 GitHub 用户名加上 ".github.io"。比如我的用户名是 qianhongbo,想开个人主站,就必须建一个名为 qianhongbo.github.io 的仓库。名字对不上,Pages 服务就不会把它识别为个人主页。
这个规则有几个细节需要注意。首先,用户名里如果带连字符,仓库名里也要原样带上,不要自己改成下划线或删掉。其次,GitHub 当前注册不允许新用户名带下划线,但历史老账号可能有,这类用户创建个人站仓库时要多加留意。另外,如果你建立的是一个普通仓库,想用它的某个分支发布网页,站点地址会变成 qianhongbo.github.io/仓库名,路径里会多一级目录。个人主站我还是强烈建议用专门的 xxx.github.io 仓库,路径干净,配置也最简单。
我第一次建站时就在这个问题上栽了跟头:先在一个测试仓库里写了不少内容,推到 gh-pages 分支后访问,发现页面都正常,但文章里引用的资源路径全都带了一级目录,导致后面迁移时改得很狼狈。
2.2 最基础的发布流程:推送即上线
理解了命名规则,发布本身反而最简单。我第一次部署的时候只做了三步:在 GitHub 上创建 qianhongbo.github.io 仓库,本地用 Git 初始化项目并关联远程地址,然后把内容推送到 main 分支。推送完成后,打开仓库 Settings 里的 Pages 面板,会看到提示站点已经发布,等几十秒再访问域名就能看到页面。
这个流程给我最大的感触不是技术上的,而是体验上的。以前用虚拟主机时,更新一个文件要用 FTP 传一遍,几百个文件传起来要等半天,改一个错别字也得重新上传对应的文件。GitHub Pages 把"发布"变成了"提交代码"之后,整个更新动作变成了一行 git push。写出这种体验对比,不是说 FTP 有多落后,而是说"发布"这个高频操作一旦变得足够轻,你更新内容的意愿会强很多。
2.3 进阶玩法:用 GitHub Actions 自动构建部署
如果只是往仓库里推纯 HTML,上面这个方案就够了。但一旦用了 Jekyll、Hugo 这类静态站点生成器,我建议你直接把构建也放到 GitHub Actions 上,让整套流程彻底自动化。你只管推送 Markdown 源码,Actions 负责在云端完成构建、生成静态文件、发布到 Pages,全程不需要本地参与。
我当时迁移到 Hugo 之后配置的 workflow 思路很清晰:监听 main 分支的 push 事件,在最新的 Ubuntu 环境里安装 Hugo,执行构建命令生成 public 目录,然后用官方或社区提供的部署步骤把 public 发布出去。第一次跑通之后,后续维护就变成纯粹的写作——本地写文章、推送、等两分钟看线上效果。写得再频繁也不觉得烦。
需要提醒的是,如果你用 GitHub Pages 的原生 Jekyll 构建,对 Jekyll 插件是有限制的,不是任何 Ruby 插件都能在仓库里直接构建。所以用非 Jekyll 生成器,或者用了超出自带白名单的插件,请务必走 Actions 自定义构建这条路线,不要和原生构建死磕。
3. 站点生成器选型:我为什么没有手写 HTML
3.1 手写 HTML 的痛,文章一多就暴露
最开始我确实想过手写 HTML。个人站起步阶段内容很少,几个静态页面之间的导航复制粘贴一下,改改链接就能用。但这个方案撑不了多久。当我开始写博客之后,问题一个接一个冒出来:每篇文章都要手动把导航栏、页脚、样式引用复制一遍,改一次导航要全局同步,漏掉一个页面就会有死链接;标签、归档、分类几乎没法用,文章多了只能靠搜索引擎碰运气;SEO 相关的 title 和 description 每个页面都得手写,稍不注意就遗漏。
静态站点生成器解决的正是这三个核心痛点。模板负责布局和导航,内容统一用 Markdown 写,生成时自动套用模板;标签、归档、RSS 这类重体力活自动生成;SEO 标签也能通过插件统一注入。换句话说,你只需要关心文字内容,其他的交给生成器。
3.2 三款主流生成器:Jekyll、Hugo、Hexo 怎么选
当前比较主流的生成器就是这三款,我列个表给后来者参考。
| 对比项 | Jekyll | Hugo | Hexo |
|---|---|---|---|
| 开发语言 | Ruby | Go | Node.js |
| 上手门槛 | 较低 | 中 | 中 |
| 构建速度 | 较慢 | 极快 | 中等 |
| GitHub Pages 原生支持 | 支持 | 需配置 Actions | 需配置 Actions |
| 主题生态 | 很丰富 | 很丰富 | 很丰富 |
| 依赖环境 | Ruby 环境 | 单个二进制 | Node.js 环境 |
最终我选择了 Hugo。原因非常实际:第一,构建速度快,文章积累到几百篇依然能做到秒级生成,本地预览时体验极佳;第二,安装简单,就是一个二进制文件,不依赖 Ruby、Node 这类运行时环境,版本管理也简单;第三,自定义能力够用,我需要的标签、归档、短代码、多语言等功能,主题里都有成熟方案。
但我也想说一句公道话:如果你对命令行不熟,或者完全不想碰构建流程,Jekyll 反而是和 GitHub Pages 结合最省事的。把源码推上去,GitHub 自动识别识别并构建,连 Actions 都不用配。只要把本地 Ruby 环境装好,Jekyll 的本机预览也很顺手。新手只求快速跑起来,Jekyll 的低门槛优势很明显。
3.3 本地搭建的一次完整流程
以我目前用的 Hugo 为例,本地从零到有一篇文章,整个流程十几分钟就能走完。
先把 Hugo 装上。macOS 用户可以用 Homebrew,Linux 用户用对应包管理器,Windows 用户下载解压出来的 exe 放进 PATH 就能用。然后创建新站点:hugo new site qianhongbo.github.io --format yaml。这个命令会自动生成一套标准目录结构,内容、模板、静态资源相互独立,很清楚。接着选一个主题放到 themes 目录,在站点配置里启用。然后创建第一篇文章:hugo new posts/first-post.md,文件顶部会生成 title、date、draft 这些元信息,填好正文后在本地启动 hugo server,浏览器打开 localhost:1313 就能实时预览。
对比前面手写 HTML 的经历,用生成器写作最大的变化是心理上的:你知道自己只负责写内容,版式、分页、导航这些都有人管,于是写作的意愿会强很多。一个工具如果能减少"写作之外的摩擦",它对你的长期价值远大于功能列表本身。
4. 部署后的经典问题:我的三次正式踩坑记录
4.1 第一次踩坑:页面打开了,样式却全丢了
第一版网站刚部署成功那天,我打开线上地址,文字内容能看,但所有 CSS、JS 全部加载失败,控制台里刷刷刷全是 404 报错。当时第一反应是文件没传全,重新 push 一次依然如此,排查了一阵发现根因是站点配置文件里的 baseURL 和实际发布路径不一致。
这个问题的原理其实不复杂。Hugo 这类生成器在生成页面时,CSS、JS 这些静态资源的路径是拼接 baseURL 得到的。如果你在配置里写的 baseURL 是 example.com,而站点实际部署在子路径上,生成的资源地址就会指向错误位置,自然全部 404。我的问题正好反过来,本地预览时一切正常,是因为本地服务器会在根路径提供资源;部署到线上后,路径一旦带了仓库名,就找不到文件了。
解决办法很简单:把配置里的 baseURL 改成最终的正式域名,重新构建推送。这里我强烈建议,在项目初始化阶段就把 baseURL 确定下来,不要心存侥幸。之后再换域名或迁路径,就涉及全局链接修改,成本比一开始配好要高得多。
4.2 第二次踩坑:Jekyll 版本和依赖冲突,成了我换 Hugo 的导火索
这段经历其实是我换掉 Jekyll 的导火索。当时我本地的 Ruby 环境比较新,Gemfile 里锁定的依赖版本和 GitHub Pages 原生构建环境默认支持的版本对不上,推送之后构建直接报错。GitHub Pages 的 Jekyll 构建是有依赖版本和插件白名单限制的,不是说你本地能跑,线上就一定能跑。我查文档、升级依赖、改语法,折腾了一个晚上,最后虽然把问题解决了,但那种"本地好好的,线上不行"的失控感让我非常不舒服。
后来换到 Hugo 加 GitHub Actions 的组合,依赖和构建流程完全掌握在自己手里,就再也没被这类问题折磨过。这里给坚持用 Jekyll 的朋友留个经验:如果你的站点依赖 GitHub Pages 原生构建,去官方文档查当前支持的版本和插件列表,在 Gemfile 里显式固定版本,不要盲目升级本地环境。如果用了白名单之外的插件,直接上 Actions 构建,不要在原生构建的死胡同里硬撑。
4.3 第三次踩坑:迁移仓库后,内部链接全面失效
这个坑完全是我自己粗心造成的。开始试用阶段,我随便建了一个临时仓库发布站点,文章里的图片和链接有一部分写的是带仓库名的绝对路径,比如 https://用户名.github.io/临时仓库名/图片.png。后来决定正式搭建个人站,内容迁到 qianhongbo.github.io 仓库,这些带临时仓库名的链接就全部失效了,文章里的图片东缺一张西缺一张,找起来特别费劲。
这件事之后我给自己定了一条铁律:站点内部所有链接,一律不写死域名。能用相对路径就用相对路径,必须用绝对路径的地方,也只在模板里用 baseURL 变量去拼。这样无论以后是迁移仓库、换域名还是改目录结构,内容都能自动适配,不用回头大规模修链接。这条经验后来也帮我避免了很多次潜在的维护灾难。
5. 把个人网站做出"作品感":域名、互动与访问数据
5.1 自定义域名与 CNAME 的完整配置
xxx.github.io 这个地址虽然能访问,但用在简历和社交主页上总感觉少了点什么。绑定自定义域名之后,网站在观感上才算完整。GitHub Pages 支持自定义域名,配置步骤其实只有两部分。
第一部分是在仓库根目录添加一个 CNAME 文件,里面写上你要绑定的域名,比如 www.example.com。第二部分是去域名服务商的控制台做 DNS 解析,把自定义域名解析到 qianhongbo.github.io 这个地址,通常的做法是加一条 CNAME 记录指向它。配置完成之后,还要到仓库的 Pages 面板里把你的域名填进去,GitHub 会校验归属并自动开启 HTTPS 证书签发,这个过程不用人工干预,等几分钟到几十分钟不等。
这里有一个容易混淆的地方:DNS 里的 CNAME 记录和仓库里的 CNAME 文件,作用完全不同。DNS 记录负责告诉浏览器"你输入的这个域名要去 GitHub 解析",仓库里的 CNAME 文件则告诉 GitHub"我的站点允许绑定哪个域名"。两者配合才能生效,只做其中一个,站点都无法正常通过自定义域名访问。
如果要用根域名,比如 example.com,DNS 配置通常需要使用 A 记录的方式指向 GitHub 提供的固定 IP 列表,GitHub 官方文档里有更新,配置前直接去查就行。嫌麻烦的话,用带 www 的域名加 CNAME 是最省心的路径。
5.2 评论和统计:静态站的互动短板怎么补
静态站最大的短板是没有数据库,评论、点赞、访问统计这些互动功能全部得靠第三方。我目前用的评论方案是 giscus,它直接复用 GitHub Discussions 作为存储后端,访客用 GitHub 账号登录后就能评论,配置上只需要填仓库名和 Discussions 的分类信息,然后往页面里插入一段 script 标签,十几分钟就能跑通。评论内容沉淀在你的仓库里,不依赖第三方数据库,数据安全和可控性都很好。
如果不希望访客必须拥有 GitHub 账号才能留言,可以考虑基于 GitHub Issues 的其他评论方案,但留言体验会稍差一些,毕竟 GitHub 这套账号体系天然带有技术社区门槛。做技术博客影响不大,做泛内容站就要慎重。
访问统计方面,我早期用过不蒜子,几行代码就能在页脚显示文章阅读数,胜在简单。后来为了数据分析和隐私可控,换成了自托管的 GoatCounter,数据存在自己的服务器上,界面干净,报告也够用。纯静态站接入这些服务都不复杂,选型时重点考虑数据归属、隐私合规和长期维护成本,避免那种突然停服导致功能失效的第三方服务。
5.3 内容维护的长期心得:网站是慢慢长起来的
网站搭好只是第一步,真正的功夫在内容的持续维护上。我自己经历几个月的折腾后,已经形成一套稳定的流程:本地写 Markdown 草稿,写完用 git 暂存并提交,推送后 Actions 自动构建发布。整个流程走顺之后,维持一个稳定更新的个人站代价非常低,低到你不会有任何心理负担。
内容策略上,我不追求日更,但尽量保证每篇文章解决一个具体问题。技术博客尤其如此,一篇能帮别人省下半天的排查文章,价值比十篇浮于表面的经验分享高得多。另外,我也会定期维护首页的项目列表和"关于我"页面,让新访客在两分钟之内知道我是谁、做过什么、最近在关注什么。个人网站的意义本质上就是把零散的输出聚合到一个长期可积累的地方,它可以是名片,也可以是作品集,关键在于你愿意持续往里面放东西。
如果你也想搭一个个人网站,我的建议是:别追求一步到位,先让一个简洁的首页上线,再慢慢加评论、统计和自定义域名。GitHub Pages 这套体系我用下来最深刻的体会是,它足够简单,简单到你只需要关注内容本身。除了有一次我自己的域名 DNS 配置迁移没做提前量,导致短时间访问异常之外,其他时间基本没为基础设施操过心。写内容、提交、推送,循环往复。网站就这么一年一年地长起来了,而这也是个人网站最有意思的地方。
本文还有配套的精品资源,点击获取