Hexo静态博客搭建教程:从环境配置到GitHub Pages部署
1. 为什么我最终选择了Hexo加静态托管的组合很多人第一次冒出自己搭个博客的念头时第一反应往往是去装个WordPress买个虚拟主机再配个数据库。这套流程我早年也走过结果就是服务器到期忘了续费数据没备份几年的文章一夜蒸发。后来我彻底想明白了个人博客这件事核心诉求其实就三个——写作要纯粹、维护要省心、成本要趋近于零。Hexo配合静态页面托管这套方案恰好把这三点全占了。Hexo本质上是一个基于Node.js的静态站点生成器。你写的每一篇文章都是本地的一个Markdown文件执行一条命令它就把这些Markdown渲染成一套完整的HTML、CSS、JS静态文件。所谓静态意思是访客打开网页时服务器只是把已经生成好的文件原样发过去不需要查询数据库、不需要执行后端逻辑。这带来的直接好处是加载极快、几乎不会被攻击、也几乎没有运维负担。那托管放在哪里这里就要说到GitHub Pages。它是代码托管平台提供的一项静态页面托管服务你只要把生成好的静态文件推送到指定的仓库分支它就会自动帮你发布成一个可访问的网站。对个人博客这种访问量不大、内容更新频率不高的场景来说免费额度完全够用。整套方案下来你唯一需要付出的就是一台能装Node.js的电脑和一点点学习成本。这篇文章适合谁看如果你是完全没接触过命令行的小白我会把每一步命令都写清楚照着敲就行如果你已经用过其他建站工具我会重点讲清楚Hexo的目录结构、配置逻辑和那些官方文档一笔带过但实际会踩的坑。我自己的博客前后迁移过三次从最初的默认主题换到现在的自定义配置中间踩的坑足够写满一整页这些经验我都会揉进下面的步骤里。先说清楚一个前提认知Hexo的工作流是本地生成、远程托管。你的源文件Markdown、配置、主题保存在本地或者一个源码仓库里生成出来的public文件夹才是真正被访问的内容。理解这一点后面很多操作你就不会迷糊——比如为什么改了文章要重新生成、为什么主题配置改了要重新部署。2. 动手之前必须理清的环境与账号准备2.1 Node.js和Git这两个依赖到底装哪个版本Hexo跑在Node.js之上所以Node.js是硬性依赖。我的建议是直接去Node.js官网下载LTS长期支持版本不要追最新的Current版。原因很实际Hexo及其大量插件对Node版本的兼容性有滞后用太新的版本经常遇到某个插件编译报错而LTS版本经过大量用户验证稳定性最好。截至我写这篇内容时Node 18和Node 20这两个LTS大版本都是稳妥选择。安装完成后打开终端Windows下是CMD或PowerShellmacOS和Linux下是Terminal输入下面两条命令验证node -v npm -v能正常打印出版本号就说明装好了。npm是随Node.js一起安装的包管理器我们后面安装Hexo就靠它。Git同样必须装。它的作用有两个一是Hexo的部署插件需要通过Git把生成的文件推送到远程仓库二是你最好用Git来管理博客的源文件方便回滚和换电脑。装完后用git --version验证。Windows用户装Git时安装向导里有一堆选项如果你不确定全部保持默认即可默认选项对绝大多数场景都是合理的。提示如果你在国内网络环境下npm安装速度很慢可以配置一个国内的npm镜像源来加速这是常规的开发环境优化手段具体命令是npm config set registry后接镜像地址。这一步不是必须的但能显著减少等待时间。2.2 仓库命名这件事命名错了后面全白搭在代码托管平台上新建仓库时命名规则是有讲究的。如果你希望博客地址是你的用户名.github.io这种形式那么仓库名必须严格等于你的用户名.github.io。这里的用户名要和你的账号名完全一致大小写也要对上。这一点极其关键我见过太多人随手起了个myblog之类的名字结果部署完访问不了排查半天才发现是仓库名的问题。如果你不想用这种根域名形式也可以起任意仓库名但那样访问地址会变成你的用户名.github.io/仓库名这种子路径形式。子路径形式会带来一个额外的坑Hexo生成的静态资源默认使用绝对路径放在子路径下会导致CSS、图片全部加载失败。解决它需要在配置文件里额外设置url和root两个字段。所以对新手来说我强烈建议直接用用户名.github.io这种根域名形式省去一堆路径烦恼。仓库的可见性选公开Public。虽然私有仓库也能配合某些付费方案部署页面但免费方案下Pages功能通常要求仓库公开。博客本来就是给人看的公开没有任何问题。2.3 本地目录规划源文件和生成文件要分开放我建议你在本地建一个专门的工作目录比如~/projects/my-blog所有操作都在这个目录里进行。不要把博客散落在桌面或者下载文件夹里因为Hexo会生成大量文件混在一起后期很难管理。更重要的是你要在脑子里把两类文件分开一类是源文件source、themes、_config.yml等一类是生成产物public文件夹。源文件是你真正需要备份和版本管理的生成产物随时可以重新生成不需要备份。理解这个区分你在做备份和迁移时就不会把没用的东西一起打包。3. 从零初始化一个能跑起来的Hexo项目3.1 安装脚手架并生成项目骨架Hexo提供了一个命令行工具叫hexo-cli我们先用npm全局安装它npm install -g hexo-cli装完后进入你准备好的工作目录执行初始化命令hexo init my-blog cd my-blog npm install第一条命令会在当前目录下创建一个名为my-blog的文件夹并把Hexo的项目骨架放进去。第二条命令进入这个文件夹第三条命令安装项目所需的依赖包。这三步做完一个最基础的博客就已经存在了只是还没生成页面。初始化完成后你会看到这样一套目录结构我逐个解释它们的用途因为后面所有操作都围绕这些目录展开目录/文件作用_config.yml站点主配置文件标题、作者、部署方式都在这里source存放你的文章和页面_posts子目录放博客文章themes存放主题每个主题一个子文件夹public生成出来的静态文件部署时推送的就是它scaffolds新建文章时的模板package.json项目依赖清单3.2 本地预览先看到效果再谈部署在部署到线上之前一定要先在本地把博客跑起来看看效果。执行hexo server或者用简写hexo s。终端会提示服务已启动默认监听4000端口。打开浏览器访问http://localhost:4000你应该能看到一个默认主题的博客首页里面有一篇Hexo自带的示例文章。这一步的意义在于建立一个反馈闭环。后面你改配置、换主题、写文章都可以先在本地hexo s看效果确认没问题了再部署。千万不要改一点就部署一次那样既慢又容易把线上搞乱。注意hexo server启动的服务是带热重载的你改了文章或配置多数情况下刷新浏览器就能看到变化。但如果你改了主题的配置文件或者_config.yml有时候需要按CtrlC停掉服务再重新启动才能生效。这个细节官方文档没强调但实际用起来经常遇到。3.3 常用命令的职责边界Hexo的命令不多但每个的职责要分清楚混用会导致莫名其妙的错误hexo clean清空public目录和缓存。当你发现改了东西但页面没变化时先执行这个。hexo generate简写hexo g根据源文件生成静态页面到public。hexo server简写hexo s启动本地预览服务。hexo deploy简写hexo d把public部署到远程。一个典型的完整流程是hexo clean hexo g hexo d。我强烈建议养成先clean再generate的习惯因为Hexo的缓存机制偶尔会抽风导致旧内容残留。这个组合命令我用了几年几乎没再遇到过改了没生效的诡异问题。4. 站点配置与主题定制让博客真正属于你4.1 主配置文件里那几个必须改的字段打开根目录的_config.yml这是整个站点的总控。文件里字段很多但新手阶段真正必须改的就那么几个title: 你的博客标题 subtitle: 副标题可留空 description: 一句话描述你的博客 author: 你的名字 language: zh-CN timezone: Asia/Shanghailanguage设成zh-CN很重要否则主题里的上一篇这类文字会显示成英文。timezone设成你所在的时区否则文章发布时间可能对不上。再往下有一个url字段如果你用的是用户名.github.io这种根域名形式就填https://用户名.github.io。这个字段影响生成的永久链接和站点地图填错了会导致分享出去的链接打不开。还有一个deploy字段这是部署配置我们放到后面专门讲。新手最容易犯的错是直接改这个字段但格式写错导致YAML解析失败整个站点生成报错。YAML对缩进极其敏感一律用空格绝对不能用Tab同一层级缩进必须完全一致。4.2 换主题从默认的landscape到更顺眼的方案Hexo默认主题叫landscape能用但确实朴素。换主题的流程其实很简单但有几个细节决定成败。主流做法是把主题仓库克隆到themes目录下。比如你想用某个主题先找到它的仓库地址然后在博客根目录执行git clone 主题仓库地址 themes/主题名克隆完成后打开根目录_config.yml把theme字段的值改成你克隆下来的主题文件夹名。注意是文件夹名不是仓库名两者经常不一样这是新手第一个坑。然后关键一步绝大多数主题都有自己的配置文件通常放在themes/主题名/_config.yml。你需要根据主题文档去改这个文件比如设置导航菜单、社交链接、头像等。这里有个我踩过的坑——主题更新时如果你直接覆盖主题文件夹你在这个配置文件里的所有自定义都会丢失。正确的做法是把主题配置复制一份到博客根目录命名为_config.主题名.yml然后在主题的配置读取逻辑支持的情况下引用它。不同主题支持程度不同换主题前先看文档说明。4.3 写第一篇文章Front-matter的门道新建文章用命令hexo new 我的第一篇文章这会在source/_posts下生成一个Markdown文件。打开它顶部有一段被---包裹的内容这叫Front-matter用来声明文章的元信息--- title: 我的第一篇文章 date: 2024-01-01 10:00:00 tags: - 标签一 - 标签二 categories: - 分类名 ---这里有几个经验点。date如果不写Hexo会用当前时间但如果你是从别处迁移文章手动指定日期能保证排序正确。tags和categories的区别很多人搞不清分类是层级式的一篇文章通常只属于一个分类标签是扁平的一篇文章可以打多个标签。我的习惯是分类用大方向比如技术笔记标签用具体关键词比如Hexo前端这样归档页和标签云都清晰。正文部分就是标准Markdown语法。Hexo还支持一些扩展标签比如插入图片、引用块、代码块高亮等。代码块建议标注语言类型主题会自动做语法高亮阅读体验好很多。提示文章的文件名会成为URL的一部分。默认情况下中文标题会被转成拼音或者一串编码看起来不美观。你可以在Front-matter里加一个permalink字段手动指定URL或者在主配置里调整permalink的生成规则。这个细节对SEO和链接美观度都有影响值得花几分钟配置。5. 部署到线上把本地成果推上公网5.1 安装部署插件并配置deploy字段Hexo本身不直接支持推送到代码托管平台需要装一个部署插件npm install hexo-deployer-git --save装完后回到根目录_config.yml找到deploy字段配置成下面这样deploy: type: git repo: 你的仓库地址 branch: main这里有几个关键点。repo填的是仓库的HTTPS或SSH地址。branch要和你仓库的默认分支一致现在新建的仓库默认分支多为main老仓库可能是master填错了会推到一个不存在的分支上部署自然失败。这是新手最高频的报错来源之一。另外如果你用的是用户名.github.io这种根域名仓库分支通常就是main。如果你用的是子路径形式的仓库有些方案要求推送到gh-pages分支具体看平台说明。配置前务必确认清楚。5.2 一次完整的部署流程与验证配置好后执行完整流程hexo clean hexo generate hexo deployhexo deploy执行时插件会把public目录的内容作为一个Git提交推送到你配置的仓库分支。推送成功后稍等一两分钟平台需要时间构建和发布访问你的博客地址就能看到线上版本了。如果访问显示404按这个顺序排查第一确认仓库名和用户名是否完全匹配第二确认推送的分支和平台Pages设置里指定的分支是否一致第三去仓库的Actions或Pages设置页面看构建状态有没有报错信息。绝大多数404都是这三个原因之一。5.3 部署这件事我踩过的三个坑第一个坑是每次部署都要求输入账号密码。用HTTPS地址推送时平台早就不支持密码验证了需要用访问令牌Token代替密码。更省心的方案是配置SSH密钥一次配置永久免密。SSH的配置流程是本地生成密钥对把公钥添加到平台账号的SSH设置里然后把repo地址换成SSH格式。这一步花十分钟配置后面几年都省事。第二个坑是部署后样式全丢。这几乎百分百是路径问题。如果你用了子路径形式的仓库必须在主配置里同时设置url为完整地址、root为/仓库名/。只改一个不改另一个就会出现HTML能打开但CSS加载不出来的情况。第三个坑是部署覆盖了源码。有些人图省事把整个博客目录都推到部署仓库里结果生成产物和源文件混在一起越搞越乱。正确做法是部署仓库只放public的内容由插件自动处理源文件单独用一个仓库管理两者互不干扰。这样你换电脑时克隆源码仓库、装依赖、重新生成就能完整恢复整个博客。6. 让博客长期可维护的几个关键习惯6.1 用Git管理源码别只依赖本地我前面反复强调源文件和生成产物要分开这里再具体说下源码管理。在博客根目录初始化一个Git仓库把source、themes、_config.yml、package.json这些提交上去。但要注意node_modules和public这两个目录不要提交它们体积大且可以重新生成。在根目录建一个.gitignore文件写入node_modules/ public/ db.json这样你的源码仓库会非常轻量克隆下来执行npm install和hexo g就能完全恢复。我换过两次电脑都是靠这个流程十分钟内把博客恢复如初。6.2 备份策略本地加远程双保险光有远程源码仓库还不够我建议再定期把整个博客目录打包备份到移动硬盘或云盘。原因很现实远程仓库依赖平台万一账号出问题或者误删仓库源码就没了。本地加远程双备份成本几乎为零但能避免那种几年心血一夜归零的惨剧。我自己是每月手动打包一次文件名带上日期保留最近几个版本。6.3 更新依赖时的注意事项Hexo和主题、插件都会更新。更新本身是好事但盲目更新容易翻车。我的做法是更新前先在源码仓库打一个tag或者提交一次确保能回滚然后只更新必要的包不要一次性把所有依赖升到最新。更新后本地hexo s完整预览一遍确认没问题再部署。如果更新后出现样式错乱或构建报错直接git checkout回滚到上一个提交几分钟就能恢复。注意Node.js大版本升级时尤其要谨慎。升级Node后node_modules里的原生模块可能需要重新编译最稳妥的做法是删掉node_modules和package-lock.json重新npm install。这一步能解决大部分升级后的诡异报错。7. 写在最后的一点个人体会这套方案我从最初搭建到现在前后用了好几年中间也动过换回动态博客的念头但每次都被静态方案太省心了这个理由劝退。它最大的价值不在于技术多先进而在于把写作和折腾这两件事的边界划得很清楚——平时你只需要打开编辑器写Markdown偶尔执行三条命令部署剩下的时间它安安静静地待在那里不给你添任何麻烦。如果你刚开始搭我的建议是先把最基础的流程跑通能发布一篇文章、能在线访问就算成功了。主题美化、评论系统、访问统计这些都可以后面慢慢加。很多人卡在第一步就是因为想一步到位结果被各种配置细节劝退。先跑起来再优化这个顺序对建站这件事特别重要。