建站记录续
2024-03-05 15:59:26 # 建站

前几天重新开始写博客,因为离上一次写已经过了很久,一些基础设施有些变动,此外也觉得之前的方案有些稚嫩,不是很满意,因此重新捣鼓了很久,这里作一个总结。


一开始对之前的pipeline感到不满,过于烦琐了,于是想找一个类似WordPress的,能集管理、配置、编辑一体的后台(所以一开始为什么不用WordPress(ˉ▽ˉ;)…),然后发现真的不好找,毕竟Hexo的slogan就是“fast, simple“,再搞个后台多少是属于化简为繁了。

不过最后还是给我找到了,一个叫做Qexo的项目,提供一个webui后台,功能描述完全满足我的设想,1.4k的star令人安心。我捣鼓了一番把它部署,兴致勃勃体验了两天感觉不尽如人意。

它的功能的确丰富,但是作为一个”在线 Hexo 编辑器“,其核心功能,编辑,不够优秀。实际上它没有自研一个markdown编辑器,而是集成了vditor,一个浏览器端的markdown编辑器。这本身是一个优秀的项目,但是不得不承认,在重度使用的场景下,它比不上Typora等客户端编辑器。一个简单的例子是,它没法简单地把图片在md格式与<img>这样的HTML格式之间切换,更别说基于这个功能的图片缩放等。

当然了,开源的好处嘛就是你可以轻易地更改源码来满足个性化需求,实际上我也不是没有尝试做个contributor为开源作贡献,这不是看不懂代码嘛😢。

好吧其实我是在issues中搜到了相关问题,开发者是这样说的:

Markdown 对这个没有标准,通过 <img> 实现的话跨平台兼容性堪忧,所以暂时无法支持。

Alright,考虑其理念是“为适配不同的应用场景而生”,这也许可以理解,毕竟一个编辑器为了使自己渲染的样式和不知道什么第三方渲染器一致,兼容性确实是重要的考量,就好像Hexo的默认渲染器有时就不能解析Typora支持的某些奇怪语法;然而vditor实际上是支持直接导出的,至少直接导出是不可能遇到任何兼容性问题的。在这个层面上来讲,给用户提供一个可开可不开,且需求广泛的功能有何不可?就算遇到了问题,也是用户自己选择承担。在这一点上Typora做的就很好,在语法上给用户提供了很强的可配置性,对一些标准外的语法,反正自己能支持能正常导出,你爱用不用。

说得有些多,回到正题,除了编辑器本身的缺陷,Qexo的图床可配置性也比较差,此外由于我听从建议把它部署在了Vercel+PlanetScale上,导致加载略慢,页面切换体验很差。以上种种让我放弃了Qexo,返璞归真用回了比较简单的办法。

不过在部署Qexo的过程中也让我学到了很多,加上本身过了这么久的知识增长,我对原先的pipeline也有了一定的微调和优化。


首先是上传及部署,原先我采用的是本地hexo deploy然后把整个静态页面push到GitHub,这样效率稍微有些低下,现在我采取配置workflow,使用GitHub Actions来自动化部署。这样只需要上传渲染前的体积较小的源文件,GitHub即可根据配置自动部署,把生成的页面更新到gh-pages分支,这样使用方便,理论上更新速度也会更快。

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
name: Pages

on:
push:
branches:
- main # default branch

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: 'recursive'
- name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
node-version: "18.15.0"
# Install pandoc for mathjax
# 这一步如果用hexo-renderer-pandoc作为依赖是需要的,现在我用markdown-it就不用了。
- name: Install pandoc
run: |
cd /tmp
wget -c https://github.com/jgm/pandoc/releases/download/3.1.11.1/pandoc-3.1.11.1-1-amd64.deb
sudo dpkg -i pandoc-3.1.11.1-1-amd64.deb
- name: Cache NPM dependencies
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.OS }}-npm-cache
restore-keys: |
${{ runner.OS }}-npm-cache
- name: Install Dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: public # The folder the action should deploy.

虽然没有系统学过配置的语法,但还是能大概理解的,抄抄改改,也弄明白了七七八八。

on即配置该workflow的运行条件,这里就是main分支被push的时候。

下面就是依次执行一些action,其中一些是官方提供的一些封装好的action,用uses即可使用,再用with来配置参数;另一些则是直接用命令行输入的指令,放在run后面。

实际上Hexo官方也给出了“一键部署”的方案,通过配置或插件实现本地deploy后自动把public的内容上传到GitHub,这与我一开始的方案其实是类似的(我估计当年是照这个学的但是没完全学明白),其优势是可以隐藏源文件,但我感觉这个方案的确不如云部署来得优雅和高效。


此外,为了实现Hexo端渲染器的高拓展性,我把之前使用的pandoc换成了hexo-renderer-markdown-it,其对markdown语法的支持度更高,更是可以直接加载markdown-it支持的大量插件,其缺乏的latex完全可以被插件弥补。

实际上我的这个选择就是因为Typora提供的一些非标准语法

Note

比如这个GitHub格式的警告框

不被支持,但是装了markdown-it-github-alerts之后就可以解析出来啦。不过装完插件虽然能解析出正确的HTML代码,但是由于没有引入样式,还是不能正常渲染。为此需要更改Hexo主题,在模板中引入CSS样式。

我这里就是把在header模板中引入了官方提供的样式文件,需要注意的是需要根据主题的夜间模式方案来微调引入的样式代码。


图床方面,我仍然使用PicGo作为图床工具(不得不说其配置比Qexo简单太多),而图床本身改用阿里云OSS,不知道是腾讯云COS本身不稳定还是因为其地区在和我当时不在一个城市又或者是我自己的某些配置问题,导致在不开全球加速的情况下图片加载非常非常慢,我于是尝试使用了一下阿里云体验良好(似乎其自带cdn加速,没深入了解),遂迁移图床。

之前在解决腾讯云COS下载慢的问题时,曾怀疑过是不是怪我上传的图片太大了(后来证明我想多了,几M的图片换阿里云就是秒传),研究了一些图片压缩方案。虽然之后不需要了,但本着节约的原则,我还是给PicGo装了一个插件,通过调用tinypng的接口实现图片上传前自动压缩。


最后的最后,我给Typora配置了一个自定义导出:

1
git add . && git commit -m "save on ${today}" && git push

这样就可以实现一键上传文章了。

考虑到新建文章还要找到源目录开cmd输指令,于是又在chat的帮助下写了一个脚本。

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
import subprocess
import tkinter as tk
from tkinter import simpledialog
import psutil
import configparser

# 读取配置文件
config = configparser.ConfigParser()
config.read('config.ini')
cmd_template = config['Settings']['cmd_template']
typora_path = config['Settings']['typora_path']

def is_typora_running():
for process in psutil.process_iter():
try:
if 'typora' in process.name().lower():
return True
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
return False

def start_typora():
subprocess.Popen(["cmd", "/c", "start", "/B", typora_path], shell=True)

def execute_command(command):
subprocess.run(command, shell=True)

def get_user_input():
root = tk.Tk()
root.withdraw()
user_input = simpledialog.askstring("新建文章", "请输入文章名:")
return user_input

def main():
if not is_typora_running():
start_typora()

user_input = get_user_input()
if user_input:
# 将用户输入嵌入到命令模板中
command = cmd_template.format(input=user_input)
execute_command(command)
else:
print("没有输入命令参数。")

if __name__ == "__main__":
main()

于是可以双击脚本输入文章名自动创建文章并打开Typora了(需要读取ini中的路径和模板),真是很有用啊!🤪

至此整个pipeline已经差强人意(我语文好不好),这通捣鼓终于告一段落。