前言

从WordPress刚转过来,感觉很爽,本主题基于butterfly:https://github.com/jerryc127/hexo-theme-butterfly 配置,本文记录Hexo建站过程中遇到的问题和相关解决方案。

先留个新站纪念图(前端小白折腾了将近一个星期来着)

image-20210129194438414

快速入门Hexo

https://www.cnblogs.com/liuxianan/p/build-blog-website-by-hexo-github.html

npm Install卡住

使用代理registry

1
npm config set registry https://registry.npm.taobao.org

来自OSS的图片无法显示

因为防盗链的原因,所以需要给每个md文件加上

1
<meta name="referrer" content="no-referrer" />

详见:https://segmentfault.com/a/1190000017896469

Hexo更换电脑重新部署

https://www.jianshu.com/p/906294181814

更换博客地址

https://www.cnblogs.com/zhansu/p/9643066.html

Debug

在hexo g的时候如果出错,可以使用hexo g --debug来找出哪个文件出了问题

音乐播放器

注意data-server选项,要根据音乐提供商的类型填,比如网易就是playlist,详见https://butterfly.js.org/posts/507c070f/#%E5%89%8D%E8%A8%80

视频播放器

插入各大网站视频https://jasonssun.github.io/2019/06/17/Hexo%E6%90%AD%E5%BB%BA%E5%8D%9A%E5%AE%A2NexT%E4%B8%BB%E9%A2%98%E4%B9%8B%E5%B5%8C%E5%85%A5%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9%E8%A7%86%E9%A2%91%E8%AF%A6%E7%BB%86%E9%85%8D%E7%BD%AE/

菜单栏图标

全部在fontawesome-webfont.svg文件中定义,当然这里有可视化版本的:https://fontawesome.com/icons?from=io

也可以引入自定义图标:https://blog.csdn.net/u012208219/article/details/106883012

阿里巴巴图标库:https://www.iconfont.cn/search/index?q=%E5%BD%92%E6%A1%A3

网站底部备案图标

不能有style样式,不然会报错。。。

域名解析+HTTPS

A是绑定ip,CNAME是绑定github.io的地址(也就是我们博客的地址),但是阿里云这边A和CNAME会冲突,所以其中一种要选境外

至于HTTP,可以直接在Github Setting中配置域名(不加任何前缀,直接根域名,效果就是https://lfzxb.top,需要前缀的话就加上前缀,例如image-20210127161647759),

不过要等十几分钟才能生效。

评论系统与邮件提醒

因为Valine的拉胯,我选择Twikoo,基于腾讯云,速度快,配置方便,功能齐全

可能会用到的相关链接

QQ邮箱SMTP:https://jingyan.baidu.com/article/6079ad0eb14aaa28fe86db5a.html

Twikoo:https://twikoo.js.org/quick-start.html#%E4%BA%91%E5%87%BD%E6%95%B0%E9%83%A8%E7%BD%B2

看板娘

直接看大神版的:https://zhuanlan.zhihu.com/p/58325389

大神仓库:https://github.com/stevenjoezhang/live2d-widget

如果懒的搞这么复杂,就直接在主题的配置文件里的inject中添加大神仓库提到的脚本即可

1
2
3
4
5
6
7
# Inject
# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
# 插入代码到头部 </head> 之前 和 底部 </body> 之前
inject:
head:
bottom:
- <script defer data-pjax src="https://cdn.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/autoload.js"></script>

不过建议按照知乎链接里那样下载下来,修改一下autoload.js中的路径,然后引用自己下载好的界面的autoload.js(可以不用设置live2d:true),速度应该会快一点

1
2
3
4
5
6
7
# Inject
# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
# 插入代码到头部 </head> 之前 和 底部 </body> 之前
inject:
head:
bottom:
- <script defer data-pjax src="/live2d-widget/autoload.js"></script>

访客地图

通过:https://clustrmaps.com/add 获取自己网站的html代码,然后在hexo博客目录的source/_data/widget.yml中添加(注意,html词条内容是自己网站的html代码,不要直接复制粘贴下面的)

1
2
3
4
5
6
- class_name: user-map
id_name: user-map
name: 访客地图
icon: fas fa-heartbeat
order:
html: <script type="text/javascript" id="clstr_globe" src="//clustrmaps.com/globe.js?d=2qXPT_cvU57wIWzaWLGcD9j8jkVmjwJZn2F-AxsFOyU"></script>

基于Github的CI集成

https://www.antmoe.com/posts/6081157f/index.html

CI代码需要单独拿出来讲一下

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
# workflow name
name: Hexo Blog CI

# master branch on push, auto run,当这个分支进行Commit的时候就会执行这个工作流,注意选对分支
on:
push:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest

steps:
# check it to your workflow can access it
# from: https://github.com/actions/checkout
- name: Checkout Repository master branch
uses: actions/checkout@master

# from: https://github.com/actions/setup-node
- name: Setup Node.js 10.x
uses: actions/setup-node@master
with:
node-version: "10.x"

- name: Setup Hexo Dependencies
run: |
npm install hexo-cli -g
npm install

- name: Setup Deploy Private Key
env:
HEXO_DEPLOY_PRIVATE_KEY: ${{ secrets.HEXO_DEPLOY_PRIVATE_KEY }}
run: |
mkdir -p ~/.ssh/
echo "$HEXO_DEPLOY_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts

- name: Setup Git Infomation
run: |
git config --global user.name '名字'
git config --global user.email '邮件'
- name: Deploy Hexo
run: |
hexo clean
hexo generate
hexo deploy

注意博客主题不能作为SubModules存在,这会导致在云端构建的时候找不到主题特定关键字而报错,例如以下报错

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
FATAL {
err: Error [Nunjucks Error]: _posts/et-fguilearn.md [Line 2, Column 7] unknown block tag: note
===== Context Dump =====
=== (line number probably different from source) ===
1 | <meta name="referrer" content="no-referrer" />
2 | <p>{% note info %}<br />
3 | 本文章已于2021.1.29更新,新增<a href="https://www.lfzxb.top/et-fguilearn/#%E5%AE%8C%E6%95%B4%E5%B7%A5%E4%BD%9C%E6%B5%81%E6%96%B0%E7%89%88%E6%9C%AC">新版FGUI插件(Lua版本)安装与配置相关教程</a>。TS版本将在未来放出。<br />
4 | {% endnote %}</p>
5 | <h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2>
6 | <p><strong>感谢<code>有招小弟的大佬吗</code>的大力支持</strong></p>
7 | <h2 id="环境准备"><a class="markdownIt-Anchor" href="#环境准备"></a> 环境准备</h2>
===== Context Dump Ends =====
at formatNunjucksError (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/hexo/lib/extend/tag.js:171:13)
at /home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/hexo/lib/extend/tag.js:246:36
at tryCatcher (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/bluebird/js/release/promise.js:547:31)
at Promise._settlePromise (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/bluebird/js/release/promise.js:604:18)
at Promise._settlePromise0 (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/bluebird/js/release/promise.js:649:10)
at Promise._settlePromises (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/bluebird/js/release/promise.js:725:18)
at _drainQueueStep (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/bluebird/js/release/async.js:93:12)
at _drainQueue (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/bluebird/js/release/async.js:86:9)
at Async._drainQueues (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/bluebird/js/release/async.js:102:5)
at Immediate.Async.drainQueues [as _onImmediate] (/home/runner/work/MyHexoAndBlog/MyHexoAndBlog/node_modules/bluebird/js/release/async.js:15:14)
at processImmediate (internal/timers.js:461:21) {
line: 2,
location: '_posts/et-fguilearn.md [Line 2, Column 7]',
type: 'unknown block tag: note'
}
} Something's wrong. Maybe you can find the solution here: %s https://hexo.io/docs/troubleshooting.html
Error: Process completed with exit code 2.

移除网站左上角标题

如果觉得左上角的那个标题多余,可以在主题配置文件中填写

1
2
3
4
inject:
head:
- '<style>#nav #site-name { display: none;}</style>'
bottom:

左上角添加天气

https://surpsec.cn/3178170368.html

文章插入PDF

1
npm install –save hexo-pdf
1
{% pdf url %}

Webp图片压缩优化

Webp是相对于png更高效的压缩方式,同时保证了一定的图片质量

推荐大家直接使用 Imagine 或者 腾讯智图 来将png/jpg/gif转为webp格式,节省大量空间和网络流量

当然了,如果之前上传过的图片就不能使用上述方法了,所幸阿里云OSS提供了数据处理功能,配置规则后只需要在原地址后加上后缀即可使用阿里云在线转Web服务,具体方法参考:https://www.maplefeng.com/aliyun-cdn-webp/

下面是我使用Webp前后的对比,非常好用

提供一个随便写的图片链接批处理工具,将此脚本编译成exe后放在博客目录运行即可

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace OperateTextFile
{
class Program
{
static void Main(string[] args)
{
// 创建一个 DirectoryInfo 对象
DirectoryInfo mydir = new DirectoryInfo("./");

// 获取目录中的文件以及它们的名称和大小
FileInfo [] f = mydir.GetFiles();
foreach (var file in f)
{
string path = file.FullName;
if (path.EndsWith(".md"))
{
WriteReplaceText(path, ReadText(path), false, ".png", ".png!webp");
WriteReplaceText(path, ReadText(path), false, ".gif", ".gif!webp");
WriteReplaceText(path, ReadText(path), false, ".jpg", ".jpg!webp");
}
}
}

public static List<string> ReadText(string path)
{
List<string> list = new List<string>();
StreamReader sr = new StreamReader(path, System.Text.Encoding.UTF8);
while (!sr.EndOfStream)
{
string curstr = sr.ReadLine();
list.Add(curstr);
}

sr.Close();
return list;
}

public static void WriteReplaceText(string path, List<string> list, bool append, string oldstr, string newstr)
{
StreamWriter sw = new StreamWriter(path, append, Encoding.UTF8);
foreach (string str in list)
{
string temp = "";
temp = str.Replace(oldstr, newstr);
sw.WriteLine(temp);
}

sw.Close();
}

}
}