使用 Hexo 搭建和部署个人网站

本文介绍了使用Hexo搭建和部署个人网站的过程,包括技术选型、博客架构、配置与插件、部署方案以及后续开发计划。Hexo因其简单的架构和良好的自定义性被选为平台,文中详细阐述了如何通过Git和CI/CD实现自动化部署,以及如何配置图床和优化SEO。还提供了多个Hexo主题的推荐和未来开发的计划,包括基于React的GUI管理工具。

技术选型

在做博客之前先了解了一下国内已有的线上博客平台,因为其在SEO和曝光(自带流量,不用手动SEO)方面有一定的先天优势:

  • CSDN:老牌国内社区,主要问题是内容质量低,充斥着广告和复制粘贴翻译的低创,公开拿开源资料来收费还把导入MD的功能砍了(根据官方的说法是保留了MD导入的)
  • 知乎:问答社区,编写体验尚可,之前在上面写过几篇NLP的文章,内容质量有点参差不齐,编写体验不错,支持MD导入
  • 掘金/思否:查资料的时候经常看别人的文章,感觉这两家的内容质量还不错,观看体验尚可,但没在上面写过
  • 博客园:默认样式很丑,需要(个人直觉)在线配置有点麻烦,但自由度高,有SEO优化,部署相对方便(特别是对国内这种需要公安备案的环境)
  • 新浪:已经死啦

上述平台中知乎、掘金、思否我会尝试同步更新,博客园随缘更新。

目前国外我了解的开放博客解决方案(或者说本地博客部署框架)有:

  • WordPress:老牌博客框架,提供自己的在线平台;功能大而全,开发语言为PHP,个人不太熟悉,但实际写作过程中几乎不用接触代码
  • Hexo:Node.JS框架,自定义程度高,整体较为轻量,适合前端开发者
  • Notion:基于数据库的知识管理平台,支持页面公开发布,个人一直在用,最近也支持了Wiki模式,但鉴于无本地和URL为uuid等特性,这里没有把他当作博客的第一选择,而仅仅是用作个人知识管理,后续考虑编写hexo插件和调用Notion API打通hexo+Notion的工作流
  • Hugo:未作了解

最终,主要是因为个人对整个Hexo生态比较熟悉,选择了Hexo平台(并不是说其他平台不好)

对个人而言,Hexo有以下优点

  • 架构简单,整个CLI都是基于Node的,对JS开发者友好
  • 使用JSON数据库存储元数据,方便扩展(缺点是体量大了可能会有性能缺陷,后续要考虑长期维护的话是一个问题)
  • 插件较多,自定义性方便(后面会给到我的插件方案)
  • 部署方便,可以直接使用Git进行CI/CD自动化部署(如Github Action)
  • 主流平台(这里我使用腾讯云)都支持直接通过serverless部署hexo(不知道什么是serverless的可以参考我的这篇博客

博客架构

Hexo采用hexo-6.3.0node-v16.17.1+npm-v9在本地构建,主题使用Redefine(可能后续会进行改动和二次开发)。

在整个博客中,Hexo作为静态网站框架,起到Hold整个Markdown博客数据库并渲染成HTML渲染其他静态网页两个作用。

如何创建Hexo博客这里就不再赘述了,网上有很多教程,这里也不做教程推荐。

Hexo配置与插件

参考我之前的项目 KiritoKing/hexo-msdoc-renderer,为博客增加以下基础功能:

部署方案

具体静态页面部署方案见下方的Serverless 部署

  • 项目源码使用Git,存储库位于Github,方便使用CI/CD自动化生成页面
  • 页面部署可以使用Github Action自动触发部署(到Github Page),但这里我使用的是腾讯云的Webify Serverless服务,其自带CI部署可以在Push时自动生成页面并部署
  • 评论系统实现采用gitalk实现,具体嵌入则由主题提供

其他页面

由于除了博客,个人网站还需要显示其他页面,目前个人有以下解决方案:

  • 直接在./source中创建对应目录映射为URL,将单页面静态网站放在目录中,使用_config.yml中的skip_render选项跳过渲染(生成时直接拷贝到public中)
  • Fork主题,添加指定页面的Scaffold代码,利用./_data动态渲染页面,模板EJS设计完成后PR
  • 利用Serverless按量计费特性,直接创建新页面绑定到另一个域名,跨域跳转

方案A适用于不会经常改变的静态页面,如个人简历;方案B适用于动态页面,如项目列表,可能需要用Github抓取信息更新yml文件来刷新页面;方案C适用于不同架构创建的页面(如React页面),且该页面可能有频繁改动的情况。

Hexo主题备选

因为做过不少Hexo外包项目,这里收集了一些我个人觉得不错的主题:

后续开发计划

目前打算开发一个基于React+Next/Electron的Hexo的GUI管理方案hexo-utils),不过不是编辑器类型而是偏管理向,按Package进行功能划分如下:

  • hexo-utils/git-utils:实现可配置的自动化Git工作流

    • 自动添加暂存区
    • 根据暂存区改动自动添加Commit Message(配合自定义commitlint使用)
    • (可选)根据Git Log自动修改文章Front-Matter修改日期
    • (可选)推送到远程仓库
    • (可选)自动化CI部署
  • hexo-utils/core:维护应用所需数据和逻辑,钩入hexo-hooks

    • 更完备的Draft管理:Draft中目录自动对应Post中目录
    • 根据Git Log自动生成和更新热力图
    • Tags管理: 维护一个本地的Tags库,为文章自动上标签、去标签、格式化标签(大小写)
  • hexo-utils/cli:为core添加CLI入口
  • hexo-utils/webui:为core添加Web-UI入口,作为hexo插件引用,用react+next实现
  • hexo-utils/client:使用electron封装core功能,支持管理多个hexo目录
  • hexo-utils/notion-utils:与Notion双向同步构建知识管理和分享体系

    • 将Draft和Post拍平后同步到Notion,使用一个Property进行区分
    • Notion/wolai导出的文章自动生成front-matter并部署
    • 同步兼容Notion和国内的wolai平台导出

Typora 图床配置

我一直都习惯用 Typora 进行写作,习惯了所以也入了正版 我一直都习惯用 Typora 进行写作,习惯了所以也入了正版 (其实是当时不知道beta可以一直用~~(其实是当时不知道beta可以一直用~~。。

图床配置

之前一直用的picgo的GUI客户端,因为最开始接触MD写作的时候并不会写前端和Node那一块,所以就用了gui,但越到后面越发现这个electron的客户端就是个性能累赘:不仅冷启动速度慢还经常卡死,而且是一个根本不必要的功能(指上传完全可以用cli实现),所以就借此机会切换到picgo-core。

切换到CLI后可以做到0秒冷启动的效果,非常顺滑,而且没有一个额外的electron进程占后台。本文所有图片均使用picgo-core上传。

首先你先要有一个包管理器(npm, yarn, pnpm)都可以:

# 这里以npm为例
npm i picgo -g

然后是配置图床,个人使用的是腾讯云COS作为图床:

  1. 访问密钥中获取你的AppId, SecretId, SecretId;在存储桶列表获取Bucket和AP位置。
  2. 建议在终端中运行 picgo set uploader运行CLI向导,运行完毕后你的配置文件应如下图所示:
  1. 在Typora中 设置 -> 图像 设置好上传服务(如果你前面配置好了就可以直接验证,也可以打开配置文件检查一下)

上传成功会得到如下提示:

  1. 配置时间戳上传,这里需要借用 picgo-plugin-super-prefix 这个插件。

首先全局安装这个包:

picgo install super-prefix

然后在配置文件里添加和修改下面的代码,就可以让图片存储在对应存储桶的YYYY/MM/YYYYMMDDHHmmss.*路径里(如*/picgo-core/2023/05/20230522221603.png):

{
  "picgoPlugins": {
      "picgo-plugin-super-prefix": true
    },
    "picgo-plugin-super-prefix": {
        "prefixFormat": "YYYY/MM/",
        "fileFormat": "YYYYMMDDHHmmss"
    }
}

Serverless 部署

腾讯云Webify服务

利益相关:无,希望腾讯看到了早日给我打钱或者把我招进去
(一些废话)这部分其实是2023年6月份才更新的,原因是想对博客做SEO优化,发现原来的部署总是失败,点开日志发现是环境缺失了一些包(详见hexo-all-minifier)。前些日子正好学习了一些CI和Docker相关的知识,也了解了微服务和无服务(serverless)部署的基础知识,正好成为了研究部署工作的契机。

在我不知道什么时候,腾讯云的整个Serverless架构都发生了变化:

  • Cloudbase 云开发:整个腾讯云微服务/无服务(serverless)的部署框架和底层平台实现,按月订阅并提供全部服务

    • 静态网页托管服务
    • 网络优化服务,如CDN
    • 后端即服务,如数据库、小程序后台等
    • Serverless服务,如云函数等
  • Webify 云开发:Cloudbase的Web应用托管服务接口,对标vercel的微服务平台,提供了网页部署功能的封装,支持按量计费

虽然腾讯的文档很乱(痛批腾讯的一贯风格),不过整个Webify的体验是明显的好于Cloudbase+静态网页托管的流程的(虽然应该只是做了一层业务封装),整个体验上看起来是对标Vercel的,甚至支持一键部署。

上图就是现在我使用的腾讯云业务现在彼此的关系,所谓“Web应用托管”其实就是Serverless部署服务+提供“快捷网页托管”相关的Docker镜像,即新方案应该就是旧方案的业务整合+拆分,并没有本质上的区别。

Web 应用托管采用按量计费模式,自身能力免费,应用按照其使用的 TCB 底层环境的各项资源独立计费,如静态托管等。

Github Page

由于腾讯云的方案无法做加载优化(资源压缩处理)和SEO优化,原因是其Hexo模板的Dockerfile是写死的(而且node版本特别老),无法进行定制,因此我被迫尝试了其他方案进行尝试。这里先尝试了Github Page,因为其开源且文档丰富。

我对这里方案的要求有下:

  • 体验对标收费的Serverless服务,即不创建额外仓库,且通过Action自动化构建流程
  • 解决原有环境问题,支持进行SEO和加载优化

    • 使用hexo-all-minifier 做资源压缩和加载速度优化
    • 使用hexo-seo 做SEO优化

部署教程

这里参考了Hexo官方教程
  1. 创建Github Pages服务,根据Github Pages文档我们需要将hexo仓库更名为 username.github.io (注意这里username和我们的用户名必须完全匹配)
  2. 编写Github Action工作流

    1. 使用 node --version 指令检查你电脑上的 Node.js 版本,并记下该版本
    2. 在储存库中建立 .github/workflows/pages.yml,具体代码如下,注意将node-version 字段的16 改成自己环境里的node版本
    3. 工作流定义在Push后会运行部署流程,并将生成的页面放在gh-pages 分支中(由peaceiris/actions-gh-pages@v3 定义)
# .github/workflows/pages.yml

name: Pages

on:
  push:
    branches:
      - main # default branch

jobs:
  pages:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js 16.x
        uses: actions/setup-node@v2
        with:
          node-version: "16"
      - name: Cache NPM dependencies
        uses: actions/cache@v2
        with:
          path: node_modules
          key: ${{ runner.OS }}-npm-cache
          restore-keys: |
            ${{ runner.OS }}-npm-cache
      - name: Install Dependencies
        run: npm install
      - name: Build
        run: npm run build
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public

  1. 在仓库的Settings → Github Pages → Source中设置分支为gh_pages
  2. 访问 username.github.io 就可以看见自己的网站啦

添加CNAME解析

  1. ./source 目录下添加CNAME 文件,内容你自己的域名,如下所示
chlorinec.top
  1. 在域名提供商处添加或修改DNS解析,我的是DNSPod,如下图所示

CDN加速

在更新完博客部署方式的几小时后,我发现我的域名已经不能正常访问了,感叹一下防火墙的速度,要是搜索引擎的爬虫有这一半快就好了。

学习过计网的同学都知道,CDN是一种部署在端侧的缓存加速方案,CDN(内容分发网络)负责缓存通过网络的内容,并将这些缓存的内容传递给就近的用户,使用户可以从就近的CDN源获取而不是远方的源服务器。

正常情况下CDN是加速网络访问,缓解主信道压力的手段,在某些不可言说的特殊网络波动因素的影响下,CDN就成了拯救页面可访问性的救命稻草。

这里我选择Cloudfare的国内服务进行CDN加速服务,因为其对个人开发者提供免费服务。

  1. 创建Cloudfare账号,点击创建网站,输入你的域名,选择服务套餐
  1. 在你的域名注册机构→域名管理处更改DNS提供商为Cloudfare提供的两个链接,这里以腾讯云为例
dayana.ns.cloudflare.com
rob.ns.cloudflare.com
  1. 等待一段时间后,Cloudfare就会接管DNS解析和CDN加速,如果你验证了邮箱也会收到邮件通知

当域名配置了HTTPS时可能会遇到“重定向次数过多”的问题,这是CDN的回源政策导致的,解决方案如下:

Cloudface默认提供了4种回源(用户请求CDN服务器,CDN服务器请求源服务器再返回给用户的过程)政策,当源网站和CDN的HTTPS(SSL)设置冲突时就会发生循环重定向。

  • 关闭:完全不访问源站HTTPS
  • 灵活(Flexible,默认情况):当HTTPS没有配置或不受信任时,会访问HTTP
    问题就出在这里,当源站支持HTTPS且配置了HTTP转HTTPS时,Flexible策略会访问HTTP,HTTP再通过源站转化成对HTTPS的访问,此时
    又会回源到HTTP,形成一个重定向闭环。将策略改成完全即可解决。
  • 完全:必须使用HTTPS访问
  • 完全(严格):必须使用受信任的HTTPS证书访问

Vercel部署

Vercel部署很简单,直接注册账号选仓库就行,一切都是自动化的。


参考链接

标题: 使用 Hexo 搭建和部署个人网站

作者: ChlorineC

创建于: 2023-04-21 16:41:00

更新于: 2025-01-11 21:00:00

版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。

Share:

Related Posts

View All Posts »

Bun 1.0 初体验体验:这口包子香吗?

Bun 1.0是一个新的JavaScript运行时,作为Node.js的替代品,提供更快的包管理和开发解决方案。尽管目前在生产环境中尚不成熟,但它集成了多种工具,支持统一模块标准和Web API,具有显著的性能优势。Bun的包管理器速度比pnpm快4倍,支持原生JSX和TS,且具备构建工具的潜力。整体来看,Bun在运行时和工具链上均有加速效果,但仍需进一步发展以满足生产需求。

WebSocket应用研究

本文探讨了在React中使用react-use-websocket库来实现WebSocket功能的最佳实践,包括如何封装WebSocket逻辑、处理连接状态、发送和接收消息,以及使用ArrayBuffer传输文件。此外,文中还介绍了Socket.IO的工作原理及其与WebSocket的区别,提供了Node.js后端服务器的示例代码,展示了如何实现低延迟的双向通信和进度反馈。

前端包管理器 - pnpm

pnpm是一个高效且节省空间的前端包管理器,通过改进的非扁平node_modules目录和硬链接机制优化依赖管理。与npm和yarn相比,pnpm在性能和兼容性上表现优越,尤其在缓存情况下安装速度更快。pnpm的安装过程分为解析、目录结构计算和链接依赖项三个步骤,采用符号链接解决幽灵依赖问题,并通过硬链接机制减少硬盘占用。pnpm还支持monorepo,并提供了操作全局store的命令。