我是如何搭建Hexo的

Hexo + Github Action + COS

前言

如果你希望部署一个hexo博客让所有人可以看到你的作品,不一定需要一个服务器。服务器价格贵,而且还需要一定的运维能力,对新手不友好。

因为hexo是一个静态网站, 对象存储(COS)上可以部署静态网站,所以hexo可以部署在 对象存储(COS)上,具体操作如何把静态网站部署在COS上可以查看对象存储 设置静态网站

关于COS

我们在使用 hexo generate时,会生成静态的网站文件在public文件夹下,所以我们只需要把public文件夹中的文件上传到COS即可完成部署,所有人都可以访问。

COS

关于Github Action

我们通过手动上传public文件夹中的内容到COS过于繁琐,而且不自动化。我们可以通过Github Action来自动化的完成这个操作。

具体流程

在本地配置好hexo,写好文章,通过git push到github,触发github action,github action把public文件夹上传到COS。

github action会做如下操作:

  • 创建一个ubuntu的虚拟环境
  • 签出当前仓库,以供后续使用
  • 安装Node.js
  • 安装hexo的环境
  • 安装COSCMD用于控制COS
  • 替换markdown文件中的图片路径
  • 构建hexo从而创建静态文件
  • 初始化COS的配置
  • 上传图片到cos
  • 上传静态网站文件到cos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
name: Upload to COS

on:
push:
branches: [ "main" ]

workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest

# 签出当前仓库,从而可以访问仓库中的文件
steps:
- name: checkout
uses: actions/checkout@v3

# 安装node
- name: 安装node
uses: actions/setup-node@v3
with:
node-version: 20

# 安装hexo环境
- name: 安装hexo环境
run: npm install

# 安装COSCMD用于控制COS
- name: 安装COSCMD
run: sudo pip install coscmd

- name: 替换markdown文件中的图片路径
run: node replace.js

# 构建hexo从而创建静态文件
- name: 构建hexo
run: npm run build

- name: 查看public
run: ls public

# 初始化COS的配置
- name: 初始化COS的配置
env:
SECRET_ID: ${{ secrets.SecretId }}
SECRET_KEY: ${{ secrets.SecretKey }}
BUCKET: ${{ secrets.BUCKET }}
REGION: ${{ secrets.REGION }}
run: coscmd config -a $SECRET_ID -s $SECRET_KEY -b $BUCKET -r $REGION

# 上传图片到cos
- name: 上传图片到cos
run: coscmd -b xjy-pic-1305858208 -r ap-beijing upload -rfs --delete ./source/pic/ /

# 上传静态网站文件到cos
- name: 上传静态网站文件到cos
run: coscmd -b xjy-hexo-blog-1305858208 -r ap-beijing upload -rfs --delete ./public/ /

replace.js如下,用于将markdown文件中的图片url替换成COS的url

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
const fs = require('fs');
const path = require('path');

const directoryPath = path.join(__dirname, 'source/_posts'); // 修改为您的目录路径

function findMarkdownFiles(dir) {
let results = [];
const files = fs.readdirSync(dir);

files.forEach(file => {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);

if (stat.isDirectory()) {
results = results.concat(findMarkdownFiles(filePath));
} else if (file.endsWith('.md')) {
results.push(filePath);
}
});

return results;
}

function processFiles(files) {
const regex = /\(\.\.\/pic\/(.*?)\.(png|jpg)\)/g;

files.forEach(filePath => {
let content = fs.readFileSync(filePath, 'utf8');
content = content.replace(regex, (match, p1, p2) => {
const originalPath = `../pic/${p1}.${p2}`;
const replacedPath = `https://xjy-pic-1305858208.cos.ap-beijing.myqcloud.com/${p1}.${p2}`;
console.log(`Replacing: ${originalPath} => ${replacedPath}`);
return `(${replacedPath})`;
});
fs.writeFileSync(filePath, content, 'utf8');
});
}

const markdownFiles = findMarkdownFiles(directoryPath);
console.log(`找到 ${markdownFiles.length} 个Markdown文件。`);

if (markdownFiles.length > 0) {
processFiles(markdownFiles);
console.log('替换完成。');
} else {
console.log('没有找到Markdown文件。');
}

关于图片的处理

我的博客中的所有图片在本地编辑时,是在本地保存的,而不是直接上传图床,所以markdown中引用的也是相对地址source/pic这个文件夹中的图片。这样能保证图片在我本地是有备份的,不会遇到图床炸了博客看不了的情况。

当我将博客上传到github仓库后,github action会把source/pic这个文件夹中的图片上传到COS,而且会调用我自己写的replace.js脚本将markdown文件中的图片路径替换为COS的路径。这样一来可以保证图片的加载速度和稳定性。

而且存储图片的COSHexo静态网站文件的COS是两个COS的存储桶。