惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
The Last Watchdog
The Last Watchdog
C
Check Point Blog
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
云风的 BLOG
云风的 BLOG
Google DeepMind News
Google DeepMind News
K
Kaspersky official blog
P
Proofpoint News Feed
Security Latest
Security Latest
The Hacker News
The Hacker News
Simon Willison's Weblog
Simon Willison's Weblog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Security Blog
Microsoft Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
WordPress大学
WordPress大学
Project Zero
Project Zero
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
L
Lohrmann on Cybersecurity
C
Cybersecurity and Infrastructure Security Agency CISA
I
Intezer
G
GRAHAM CLULEY
A
About on SuperTechFans
S
Securelist
P
Palo Alto Networks Blog
T
Tor Project blog
罗磊的独立博客
C
Cisco Blogs
Microsoft Azure Blog
Microsoft Azure Blog
Know Your Adversary
Know Your Adversary
NISL@THU
NISL@THU
Latest news
Latest news
博客园 - 叶小钗
C
CERT Recently Published Vulnerability Notes
U
Unit 42
AWS News Blog
AWS News Blog
J
Java Code Geeks
小众软件
小众软件
D
Docker
The Cloudflare Blog
Cisco Talos Blog
Cisco Talos Blog
B
Blog
V
Vulnerabilities – Threatpost
V
V2EX
GbyAI
GbyAI
博客园_首页

愆伏

vue feedback 指令开发 通过webpack对css压缩后所引起的重名问题 NPM 撤回已发布的版本 昆虫有趋光性吗 数组转成字符串(css 属性) 关于grid布局的一些思考 阿里云和腾讯云网站字体族对比 Vue组件抛事件和Function prop的差别 Vue 事件参数传递 Vue Data里面下划线命名无效并报错 使用sublime中的正则处理数据格式 通过nodejs创建目录与文件 macOS 下npm run dev 无法局域网访问 mac 下使用ssh访问非22端口的gitlab 世界是平的,在科学上网之后 使用sublime text3和Markdown来写博客 如果非要给一个标题,那就是2014年非工作总结 不专业呢,就别捣乱 对知乎大号怒撤事件的一点看法 拒绝SB思维 嘀嘀与快的的商业博弈 关于收藏夹功能的思考 你居然都不用微信 一个英语培训机构的外呼电话 智商是硬伤就无解了 扁鹊三兄弟 竖子不足与谋 美丽说、蘑菇街今天一定开了好几个小时的会 个人独立博客会死掉吗? iPad作画 google reader即将关闭,谁来候补? 去年 美国人又火星了 一个简单的flash射击游戏 Draw an angry bird with pure CSS 用css3画一坨屎 一只音箱——漫步者M0pro 瓢虫图标 如果能够收集到世界上所有人的梦 作为一名产品经理 wordpress换域名 程序员和站长之间资源的交换 独角仙饲育日记1 男人是得有点装备的 镇江火车站、新汽车站到香逸渔港大酒店路线 jquery的slideUp、slideDown在IE中的闪动bug 《玩赚你的网站》是本难得的好书 腾讯微博邀请,欢迎自取 福特2010最新款家用普及型车 关于小霸王是否可以玩魔兽世界的问题 君要臣死,臣不得不死 wordpress主题发布:iCake 1.0 脆弱的域名服务 舍身成仁,舍己为人 欲练神功,挥刀自宫——在没有google之后 杯具掉的手作软陶皮卡丘 凶猛的阿凡达 js+css控制字体变换 2009年下半年南艺自考设计素描(本科) 愤怒摔食图——去TMD的xxx 改裤衩 紫金山捉虫记 态度问题还是能力问题 慷慨的饭店老板 南艺自考顺利达标 2009上半年南艺艺术设计自考毕业设计 说说产品经理-前言 在线生成卡通头像 CG weaver 1~3期打包下载 育儿网招聘网页设计师 google calendar的另类用法 互联网产品、运营二三事 小情调 干切牛肉雪菜面加煎蛋x2 永远的龙珠 M8:我不是山寨 终于回来了 还不都为了大客户 古典音乐——冷笑话 豆瓣盈利能力堪忧? 骑马与砍杀(mount&blade)——另类的爽快 溺爱的代价 开心不开心? 超赞的视频广告——wario land shake 神奇的《孢子spore》 该相信用户的话吗? chrome——google浏览器真的来了! 浏览器:web世界之门 赤壁——三国梦 项目管理就是博弈 Pia ji 一声的快感 Memories 拿来主义 一声叹息 禅心 LBS^2转到wordpress2.5 尽我们所能帮助灾区,希望灾民平安度过难关 游高崇寺 Avant Browser的复兴 “知”的提升
jekyll 迁移至 hexo
tortorse · 2021-10-05 · via 愆伏

2021 年之后工作忙的飞起,却又无事足道。趁着国庆假期,折腾了一下博客,将原来的 jekyll 替换为了 hexo。期间踩了一些坑,以下仅以记录。

更换原因

回想起迁移的原因,突然间竟觉得有些复杂。最初 jekyll 用的好好的,从写作到发布的流水线也跑的比较顺,如果不是闲的蛋疼,断然是没有更换的必要。只不过原来的 jekyll 版本中一直含有「暗伤」,即:评论功能要使用科学上网工具才能使用。之前也找过一些方案,大致思路是使用一个反向代理来访问 disqusAPI。具体的实现方案,网上各有所表,始终不能满足自己的需求。

这两天得闲,又在网上搜索起来,发现了 DisqusJS 这个方案,使用起来好像也挺简单,反向代理的代码别人也提供了 disqusjs-proxy-vercel, 正巧我也在使用 vercel,那就折腾一下呗。

仔细看了一下说明文档,顺带访问了使用案例中的几个博客。嗨,怎么都是 「Powered by Hexo」呢?回头再看看自己的 jekyll 博客,虽然主题用的是高仿 「Next」(Hexo 上的著名主题),可想改改前端模板部分,居然感觉无从下手。再想想当初搞 jekyll 折腾 Ruby 的过往,索性换成 NodejsHexo 算了, 就算出了什么岔子,大概率也不用从头学起,现代前端的 node、npm 总还是知道在什么地方找问题的。

操作步骤

按照比较正统的工程做法应该是:

  1. 备份数据
  2. 创建新的站点
  3. 迁移数据
  4. 上线新的站点
  5. 域名记录变更
  6. 下线旧站点

这套工程实践没太大问题,而且对于风险也有较好的应对方案,比如万一搞砸了,还可以反向执行一遍回滚到原来的状态。可是,毕竟手头没有那么多宽裕的资源和时间,直接更新算了。所以大致分为以下几步:

  1. 打开冰箱门
  2. 把大象塞进冰箱
  3. 把冰箱门关上

说人话就是:

  1. 在原来的站点上直接改代码
  2. 把新的代码更新上线,直接替换旧的站点

这样考虑基于:

  1. 个人博客没有什么用户数据,文章数据就是代码,在 Git 仓库中有版本记录
  2. 要搞多个生产环境,域名记录变更都有时间开销,直接代码更新花的时间更少

本地环境搭建

按照 Hexo官方的说明 对于熟悉 npm 的进阶用户,可以执行

1
$ npm install hexo

然后通过

1
$ npx hexo <command>

或把 node_moduleshexo 加入环境变量后使用

1
$ hexo <command>

这两个我都试了,并没有什么用。直到我按照常规方法在 package.json 中添加了 scripts 来做了 npm run 的映射,才可以通过

1
$ npm run hexo <command>

进行使用

为了不这么恶心,干脆做回小白用户全局安装了 hexo

1
$ npm i hexo -g

为了测试效果,我还是在 package.json 中添加了几个 scripts

1
2
3
4
5
6
7
8
9
10
{
...
"scripts": {
"build": "hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server"
},
...
}

按照 Hexo官方的说法,我就只需要拷贝一下 _posts 里的文件就行了。

直接 yarn run server 后,除了一堆报错,并没有什么效果。开了一个全新的 hexo 项目跑了一下,才明白首先要执行 hexo init 命令,于是我又屁颠屁颠的执行了 hexo init。继续报错,大意是: 文件夹不是空的,没办法初始化。

此时进入了逻辑黑洞,初始化就得是全新的开始,迁移就肯定不是空白的项目,但是要迁移之后能运行,又得执行初始化命令。这不是死局了吗? 又查看了一下Hexo文档,手动将 Hexo 所需的文件都建好,再把原来的 jekyll 的文件删个七七八八,终于生成成功。

分支合并

为了以防万一,前面的所有操作都在一个新开的分支 Hexo 上完成,最后则利用 GithubPull Request 合并至主分支上并完成部署。由于之前的博客使用了 vercel 部署,新建 Pull Request 会触发 vercel 的构建,构建通过后才进行真正的合并操作。到此时为止,一切都那么顺利。

设置主题

Hexo 的默认主题是 landscape,我还是想换回 「原版」的 Next。继续按照 Next的官方文档 的说法,直接进入博客目录

1
$ git clone https://github.com/theme-next/hexo-theme-next themes/next

然后再把博客的 _config.yml 中的 theme 改为 next。 官方还提供了几种方式,比如直接下载文件,下载指定文件之类的。为了方便,不纠结直接用官方默认推荐的吧。

令人感到困惑不已的是,NextGithub 上居然有两个仓库,一个是 theme-next,一个是 next-themetheme-next提供了 npm 安装的方式, 而 next-theme 则没有。当然这些都是事后发现的,官方的 Github 并没有更新有关文档,而是写在了 官方站点的文档 里。

集成好了主题之后预览,发现和原来的主题还是不一样。查了下资料发现 Next 主题分成了几种 Scheme:

  • Muse
  • Mist
  • Pisces
  • Gemini

原先博客用的正是其中的 Pisces,可是要去哪里修改这个配置呢?博客的主题配置项内并没有相关设置。自己观察一下,themes/next 下居然也有一个 _config.yml,把里面的 Scheme 修改一下:

1
2
3
4
5



scheme: Pisces

其他七七八八的设置,也按网上找的一个 文档 改改。

还是不要随便找个文档看,官方文档 还是所有文档里最靠谱的

此时,本地预览一切正常。我主要进行了以下操作

迁移文章

迁移文章很简单,直接把原来的 _posts 文件拷贝到 source/_posts 即可。我的博客带着沉重的历史,所以每个 .md 里都有一个 permalink,且原来的 permalink 都不会带有后缀 .html,我尝试设置了博客的 _config.yml 中的

1
2
3
pretty_urls:
trailing_index: true
trailing_html: true

发现无论怎么设置,产生的文件都不会带有 .html 后缀,这就导致直接浏览器预览的时候无法正常打开页面,而是直接下载文件。不浪费时间,索性一把梭把所有 .md 中的 permalink 都删除。 具体方法是使用 VSCODE 的全局搜索功能,搜索 _posts 文件夹下所有文件,并打开正则模式,搜索 permalink: (.*) 全部替换为 「空」 即可。

迁移页面

原来的博客里除了博文之外,还有「关于」、「标签」、「实验室」几个页面,这部分 Hexojekyll 非常类似,只要在 source 下建立对应的文件夹,并放入一个 index.md,写好 Front Matter 即可。

比如「关于」页面,就在 source 下建立一个 about 文件夹,里面放一个 index.md 文件,内容为

1
2
3
4
5
6
---
title: 关于
layout: page
type: about
---
...

还原功能

最主要的数据迁移完成之后,开始还原原来博客的功能。所有的 jekyll 下面有的,Hexo 都支持。

侧边菜单

themes/next/_config.yml 查找 menu,把它改成自己要的:

1
2
3
4
5
6
7
8
9
10
menu:
home: / || fa fa-home
categories: /categories/ || fa fa-th
about: /about/ || fa fa-user
archives: /archives/ || fa fa-archive
tags: /tags/ || fa fa-tags
lab: /lab/ || fa fa-flask



其中「搜索」菜单是打开本地搜索自动增加的,所以这里不用设置

menu 下的每一项代表一个菜单,前面的 key 代表菜单名, 后面的 value 分为两部分。|| 前的是路径,|| 后的是图标。看名字就知道使用的是 font-awesome 字体图标库,所用图标标识出门左转去 fontAwesome 找吧。

i18n

菜单改完,预览都是英文的,设置 _config.yml 里的 languagezh-Hans,还是英文的。进入 themes/next/languages 一看,原来这里的文件是 zh-CN.yml。这就对不上啊,改成 zh-Hans.yml 后搞定。因为我自己的 menu 里加了点东西,所以这里在多语言文件里也加上对应的。

Next 官方在 6.0 以上版本特意的把 zh-Hans 改成了 zh-CN

Google Analytics

themes/next/_config.yml 查找 google_analytics, 把 tracking_id 填上 UA-********-* 这样的值即可,和原来 jekyll 差不多。

themes/next/_config.yml 查找 disqusenabletrue, shortname 填注册的 disqus 用户名。在搜索 disqus 发现有 disqusjs 的设置,前面说过,要用起来需要搭建反向代理,以后再说吧。

Latex

我的个别几篇文章里面用到了公式,所以需要开启。Next 里面提供 MathjsKaTex 两种方案,官方也给出了说明对比。折腾了一下发现太麻烦,得修改原来书写公式的方式,而且都会在前端额外注入 js。误打误撞发现了 hexo-filter-mathjax,使用的是服务端方式,也就是说在构建时就直接生成了公式,这岂不美哉?用之!

凡事有得必有失,使用这个插件后, 1. 需要将 Hexo 的渲染器改为 hexo-renderer-pandoc 2. 需要将 Nextmath.mathjax.enablemath.katax.enable 统统设置为 false 3. 需要在用到公式的博客的 Front Matter 里添加 mathjax: true

还好,这些都是小事。

安装插件:

1
$ yarn add hexo-filter-mathjax

换渲染器:

1
2
$ yarn remove hexo-renderer-marked
$ yarn add hexo-renderer-pandoc

全套搞完之后,本地预览公式正常,和原来一模一样。

该插件依赖了 pandoc,导致在 vercel构建栽了跟头,此处不表,后面详述。

fancyBox

预览时发现图片直接都显示出来,点击没有放大效果,原来 jekyll 主题里这一部分是通过 fancyBox 实现了,这里应该也类似。 在 themes/next/_config.yml 查找 fancybox,设置为 true

本地搜索

themes/next/_config.yml 查找 local_search,把 enable 设置为 true,这样菜单里的最后一项将会多出一个 「搜索」,点击「搜索」,熟悉的搜索弹窗出现了。

自动摘要截断

按照官方的说明,在 themes/next/_config.yml 设置了 excerpt_descriptiontrue,并没有什么用。Next 官方在某个版本里删除了这个功能,意不意外,惊不惊喜? 按照官方的推荐,安装 hexo-excerpt

1
$ yarn add hexo-excerpt

然后配置博客 _config.yml,根据我自己的需求,我改成了这样

1
2
3
4
5
excerpt:
depth: 1
excerpt_excludes: ['img', 'h2']
more_excludes: []
hideWholePostExcerpts: true

新增功能

字数统计和阅读时长

看到别人博客里有本文多少字,大约需要多少分钟读完,发现也支持了,具体使用 hexo-symbols-count-time 插件。首先先安装

1
$ yarn add hexo-symbols-count-time

然后在博客的 _config.yml 里添加:

1
2
3
4
5
6
7
8
symbols_count_time:
symbols: true
time: true
total_symbols: true
total_time: true
exclude_codeblock: false
awl: 2
wpm: 275

正如前文所言,先按照 disqusjs-proxy-example 中的方法搭建反代,直接用 vercel 部署好,将部署完成后的域名填写到 themes/nextdisqusjs 部分里即可完成。此处直接按 disqusjs 文档 操作即可.

提交修改

本地预览一切就绪,准备提交到远程的 Github,让 vercel 部署。然而,提交不了了。想了一下,问题就出在最开始提到的 Next 主题安装环节。本来的博客属于一个 Git 仓库,里面又克隆了 Next 主题的仓库。对主题配置的修改都在主题仓库里,那提交到哪里去?提交到 Next 官方的仓库吗?

按照现代前端的逻辑,安装的应该是个 npm 包啊,而且大概率不会去修改 node_modules 里的东西。事已至此,看看怎么处理吧。 即然不可能提交到 Next 官方仓库,那么我们就把官方仓库 Fork 一份出来呗。然后通过 git remote 的命令把 themes/next 的远端仓库设置为我自己的 Fork 出来的仓库地址。

现在有了两个仓库,这两个仓库管理原则上是独立的,凭啥博客的仓库会更新和纳入主题的仓库内容呢?Git Submodule 即时登场,利用 git submodule addthemes/next 作为子模块加入了博客仓库。提交、推送这些常规操作都可以完成了。然后在 Github 里创建一个新的 Pull Request,开始发布前预构建。

vercel 部署

构建模板修改

第 1 次构建失败,错误出现在构建完成时

1
No Output Directory named "_site" found after the Build completed.

这是因为忘记了修改 vercel 的构建模板,在 vercelSettings 面板下的 Build & Development Settings 中,把原来的模板 jekyll 修改为 Hexo

手动安装 Pandoc

第 2 次至第 N 次,打包一开始就报 ERROR,一直报

1
pandoc exited with code null.

查了资料,有文章说是因为博客里面包含引号导致,解决方案是卸载。这?这?这是自断一臂吗?继续查继续试,最后发现是因为 vercel 的构建环境里压根没有 pandoc 啊,预装列表 别人写好了。那我自己装吧,又找到了 一篇文章 说是自己把 Pandoc 的安装包从 deb 转为 rpm, 然后上传到自己的仓库里再用构建命令调用。这?不应该吧?继续找,又找到了一篇时间较近的文章,而且名字一看就相当靠谱 Running a Pandoc build on Vercel,按照文章说的,自己在博客仓库内建一个 build.sh,内容为

1
2
3
4
5
6
7
yum install wget
mkdir pandoc
wget -qO- https://github.com/jgm/pandoc/releases/download/2.11.1.1/pandoc-2.11.1.1-linux-amd64.tar.gz | \
tar xvzf - --strip-components 1 -C ./pandoc
export PATH="./pandoc/bin:$PATH"

yarn run build

vercelsettings 面板中找到 Build Command 打开 OVERRIDE 开关,输入 sh ./build.sh 之后保存,终于构建成功。

修改 submodule 的 url

构建开始时,始终会报获取 submodule 失败

1
Warning: Failed to fetch one or more git submodules

原因是 vercel 不支持 ssh 协议的 url, 之前有人遇到过,改为 https 即可修复。当然这样的话,仓库地址必须是公开的,有一定的安全风险。如果想要使用私有仓库,则可以参考 Vercel private submodule 中的方法