教你用netlify或vercel完全自动部署hexo

1.完全自动?

【教程】hexo搭建博客+keep主题美化 里面,就提到过使用netlify或者vercel来部署hexo。但是那个是部署的静态页面

  • 部署静态页面仓库,类似github pages,需要主动hexo d才会有更新
  • 直接帮你从hexo配置文件部署,只需要git push更新源文件仓库

之前的博客中,提到的是第一种方式。本文中是第二种方式的教程。直接从配置文件部署,有以下几大好处

  • 任何地方,只要有网,你都可以通过修改github仓库中的source/_post里面的md文件,实现更新博客
  • 如果你更换了电脑,无须再为了hexo配置node.js等环境。这对于不写前端的我来说很棒

话不多说,直接开始!

2.github仓库

要做到这一点,先需要准备一个存放hexo配置文件的仓库。本地的如下文件夹,就是hexo的配置文件

image-20230323232211389

准备配置仓库,需要保证node_modulespublic文件夹不要上传到仓库中,否则后续部署会失败。这是我的gitignore文件,仅供参考

1
2
3
4
5
*.deploy_git/
db.json
*public/
.git/
node_modules/

最终仓库的文件层级如下,为了防止文章被过容易的盗走(因为仓库里面有md文件,盗文章太容易了。虽然html也能被爬走),我将其设置为私有仓库了

image-20230323232345276

有了这个仓库之后,就可以进行后续操作了

3.netlify

先新增一个site,选择从existing project中import

image-20230323232500319

这需要你的netlify账户有github的授权。我是直接用github登录的,所以已经有授权了

image-20230323232630595

选择hexo配置文件的仓库

image-20230323232643226

build命令修改为npm run build,其余不动

image-20230323232711590

到这里就可以deploy了!就这么简单!过一会成功了之后,就会显示出你的站点链接了!

image-20230323232759075

需要注意的是,nelify默认提供的二级域名,国内极有可能无法访问

image-20230323232839494

不用担心,你只需要在domain settings里面添加你自己的域名,访问速度就能起飞了

4.vercel

和netlify的操作很像,选择git仓库

image-20230323233050652

模板选择hexo,其他设置都没必要动。其中build需要进行的命令操作,已经在我们选择hexo目标的时候就选择上了

image-20230323233106194

vercel会开始部署

image-20230323233124303

如果没有报错,那就是部署成功了(否则请检查你的仓库里面hexo配置文件是不是少了或者多了什么)

image-20230323233202981

完美,也部署好了!

image-20230323233211667

vercel提供的子域名也有无法访问的问题,同样的,绑定了自己的域名就能在国内访问了。


对于我来说,这两个平台都很不错,但是vercel有个很大的“缺点”,就是干了什么都要给你邮箱发个信息,还找不到地方关闭。对于我这种强迫症来说很不友好!!!

20230426150929.png

5.遇到的问题

文章更新时间不准确?

我部署之后,遇到了vercel和netlify自动部署时会将所有文章的更新时间给重置为最新commit的时间的问题。说人话就是所有博客的更新时间都变成了你最后一次提交git的时间

这是因为其实netlify和vercel的自动部署,都是主动去git clone你的仓库的,此时它创建的文件夹肯定是全新的一个文件夹,所有文件的修改时间都是刚刚clone的时间,默认情况下hexo用的就是文件的修改时间来做更新时间,所以就会出现这种问题。

这样肯定不是很好,违背了更新时间的本意,用如下博客里面的办法就能解决这个问题;

https://blog.im0o.top/posts/c6d9de72.html

我采用的是在所有md文件的front-matter里面添加updated字段的方式(这是hexo支持的更新时间字段,格式和date字段完全相同)

1
2
date: 2023-12-08 20:32:14
updated: 2023-12-08 21:32:14

我使用了博客中提到的powershell脚本的方式来批量修改md文件,它会根据git log中的commit记录来获取当前md文件最后一次修改的时间,并写入front-matterupdated字段中。

将如下内容写入一个update.ps1文件,然后直接用windows的powershell中./update.ps1执行它就可以了

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
$fileEncoding = "UTF8";

Function Convert-FromUnixDate ($UnixDate) {
[timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($UnixDate))
}

$fileNum = 0;
Get-ChildItem -Path "./source/_posts" -recurse *.md | ForEach-Object -Process{
$fileNum = $fileNum + 1;
if ($_ -is [System.IO.FileInfo]) {

$filePath = $_.FullName;
Write-Host('{0}. {1}' -f $fileNum, $filePath);

$lineNum = 0; # yaml 格式占据行数
$yamlStartEndNum = 0;
$existUpdated = $false;
$updatedNum = 0;
$newstreamreader = New-Object System.IO.StreamReader($filePath);
while (($readeachline = $newstreamreader.ReadLine()) -ne $null) {
$lineNum = $lineNum + 1;
$temp = $readeachline -replace " ","" -replace "\n",""
if ($temp -match "---") {
$yamlStartEndNum = $yamlStartEndNum + 1;
}
if ($readeachline.Contains("updated:")) {
$existUpdated = $true;
$updatedNum = $lineNum;
}
if ($yamlStartEndNum -ge 2) {
# yaml end
break;
}
}
$newstreamreader.Dispose();

$filedata = Get-Content -Path $filePath -Encoding $fileEncoding;
$oldYamlStr = $filedata | Select-Object -First $lineNum

# git log format: https://www.cnblogs.com/ckAng/p/11205055.html https://git-scm.com/docs/git-log
# 此文件 最后一次 commit 的 Unix时间戳
$dateUpdated = git log -1 --format='%ct' $filepath
$dateUpdated = Convert-FromUnixDate $dateUpdated
$dateUpdated = $dateUpdated.ToString("yyyy-MM-dd HH:mm:ss");
$newUpdated = "updated: " + $dateUpdated;

#Write-Host("newUpdated: " + $newUpdated)

$newYamlStr = ""
# 注意: yamlStr 是一个数组, 每一个元素为一行字符串
$tempOldYamlStr = $oldYamlStr;
if ($existUpdated) {
#Write-Host($yamlStr[$updatedNum-1])
$oldUpdated = $oldYamlStr[$updatedNum-1];
$tempOldYamlStr[$updatedNum-1] = $oldYamlStr[$updatedNum-1] -replace $oldUpdated,$newUpdated
}else {
# 修改 yaml 结束行
# TODO: 好像取到的这一行不包括 最后的换行符, 导致加一个 换行 反而多了, 不过为了保险, 还是加上一个换行
$tempOldYamlStr[$lineNum-1] = $newUpdated + $([System.Environment]::NewLine) + "---" + $([System.Environment]::NewLine)
}
$newYamlStr = $tempOldYamlStr

Write-Output $newYamlStr


$newFiledata = $newYamlStr + $filedata[$lineNum..$filedata.count]
$newFiledata | Set-Content -Path $filePath -Encoding $fileEncoding

}
}

#Write-Host("更新 updated 完成");

使用该脚本过程中,我还遇到了一个文件编码导致的问题,记录在了如下issue中 https://github.com/Qexo/Qexo/issues/395

主要问题如下图所示,其实就是md文件编码不一致,导致出现了一些奇怪的红点。用python来批量修改一下文件编码格式就能解决这个问题。

image-20231209101914007

The end

有问题可以在评论区提出~