Hexo + GitHub Pages 静态网站
最近我偶然得知 GitHub 的用户名是不能占着茅坑不拉屎的,详见 Name Squatting Policy(Squatting 也很精髓了),所以我就发邮件拿到了这个 2011 年就曾经注册了的用户名。再加上机缘巧合在去年一系列的事情导致我学到不少 Web 的知识,我准备慢慢改一下这个网页,所以就干脆整理下当时怎么折腾 GitHub Pages 的。
简单介绍:Github Pages 是一个托管静态网页的平台,静态网页就是没有后台数据库,仅加载一些 Html、CSS、JS 文件,很多对象存储服务和代码托管平台都自带这一功能,比如阿里云 OSS、腾讯云 COS、Amazon S3、Coding 等,还有一些专门提供这种服务的网站如 netlify 等。Hexo 就是用 markdown 文件生成这些静态网页的工具,除此之外还有 jekyll 等。
写作需要学习一个 markdown 语法,再学一个 Git 就更好不过,花不了多少时间。
以 Windows 10 (1809) 为例,在多台电脑之间同步的部分,另一台电脑同样为 Windows 10。在 macOS Catalina (10.15.2) 也这样用过,没什么问题。
Table of Contents
- 安装 Hexo
- 配置 GitHub
- 配置 Hexo 以及部分命令
- Amazon S3 + CloudFront 图床
- 多台电脑之间同步
- 更新 Hexo 的版本
- Terminal 配置代理,及 Homebrew 的安装(Mac)
安装 Hexo
下载安装 Node.js: nodejs.org,目前 10.15.3 LTS 一路 Next 即可。成功的话 cmd 输入
node -v
或npm -v
应返回版本号。mac 用 homebrew 安装也可以。下载安装 Git: git-scm.com,目前 2.21.0 也可以一路 Next。default editor 可以换一个,PATH environment 可以改成
Git Bash Only
。成功的话任意位置右键菜单应该出现Git Bash Here
。创建一个文件夹,在 cmd 中 cd 进入,然后
npm install hexo -g
,完成后hexo init
初始化这个文件夹,完成后会显示INFO Start blogging with Hexo!
。-g
是全局安装参数,不会安装到当前文件夹中,init
会初始化这个文件夹,初始化后在当前目录可以使用hexo -v
看到版本号,没有初始化的目录只有 hexo-cli 版本- hexo-cli (command-line interface) 集成了 hexo 的一些命令用来生成和部署等,会自动附带装上
- 输入
hexo g
完成后hexo s
(提示端口占用加上参数-p <port>
),浏览器访问http://localhost:4000
可以看到 Hexo 生成的 Hello World 页面。会多出一个 public 文件夹,里面就是生成的网页。之后就用不到 cmd 了,所有命令都在 Git Bash 中进行即可。
配置 GitHub
注册一个 GitHub 账号。
在 GitHub 中建立一个 repository,输入 Repository name,必须为
<username>.github.io
。在刚才的文件夹上右键
Git Bash Here
,然后输入git config --global user.email "<github-email>"
以及git config --global user.name "<your-name>"
,邮箱必须是 Github 账户里的邮箱之一或者 GitHub 提供的 no-reply 邮箱,不然,倒也没啥问题,只是 commit 不会关联到自己的账户了。名字随意, GitHub 只靠邮箱关联用户名和用户: About commit email addresses, Setting your commit email address in Git。输入
ssh-keygen -t rsa -C "<github-email>"
,出现的几个提示都直接按回车,生成 SSH 连接的密钥。然后输入eval "$(ssh-agent -s)"
,添加密钥到 ssh-agent,成功后显示 Agent pid。最后再输入ssh-add ~/.ssh/id_rsa
,添加生成的 SSH key 到 ssh-agent,成功后显示 Identity added。在 GitHub 的
Settings -> SSH and GPG keys
界面,点击New SSH key
,把id_rsa.pub
文件里(一般在C:\Users\<User Name>\.ssh
)内容复制进去。输入
ssh -T git@github.com
测试添加是否成功,成功会显示你的 GitHub Username。第一次使用 SSH 时会显示:
The authenticity of host 'github.com (13.229.188.59)' can't be established. RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. Are you sure you want to continue connecting (yes/no)?
输入 yes 后会加入到 known host 中。
配置 Hexo 以及部分命令
npm install hexo-deployer-git --save
。一个部署到 GitHub 的插件,必须要装。--save
会把包安装到当前文件夹的 node_modules 中,并在 package.json 里添加相关 dependencies 内容:"hexo-deployer-git": "^1.0.0"
在
_config.yml
里填写Site
部分看着填,里面的language
会影响多语言的主题,我习惯用en
,这样页面的导航内容就是英文。url
一定要填,否则一些链接会出错;permalink
我改成了:title/
,这样链接会比较短,而且没有数字看上去和谐点。这个属性可以在 markdown post 的 front-matter 部分写上新的覆盖掉这个设置post_asset_folder
有人可能需要这个功能,详见 Hexo Docs - asset-folders,我不需要在首页显示完整全文就没开启theme
填主题的文件夹的名称deploy
部分,type: git
;repository 为 GitHub 的 SSH;branch: master
;message
可选,如果没有这一项的话,每次 git commit 的信息为Site updated: YYYY-MM-DD HH:mm:ss
【不同 theme 会有区别】修改 theme 的
_config.yml
,以及/language/zh-cn.yml
底部的内容。- 如果是源码,在 theme 文件夹上 Git Bash Here 运行
npm install
,会新建 theme/node_modules 并将相关依赖安装在内。然后npm install -g grunt-cli
全局安装 grunt,最后grunt buildProd
(这会构建 theme,比如把 sass 编译成 css 等等,在theme/source/assets
下)。 - 在大局域网内,
npm install
经常有问题,如果看见一堆ERR!
多半是需要梯子。一般问题出在 sass-node,它通过 github release 下载,可以在 theme 下放一个.npmrc
文件给它指定成淘宝源,内容如下1
2
3
4sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
phantomjs_cdnurl=https://npm.taobao.org/mirrors/phantomjs/
electron_mirror=https://npm.taobao.org/mirrors/electron/
registry=https://registry.npm.taobao.org
- 如果是源码,在 theme 文件夹上 Git Bash Here 运行
启用分类/归档/标签功能,其实就是生成三个文件夹在
hexo/public
下,回到 Hexo 的 Git Bash 中输入hexo new page "all-categories"
、hexo new page "all-archives"
、hexo new page "all-tags"
,然后修改三个 markdown 文件的内容为如下形式1
2
3
4
5---
title: all-archives
layout: all-archives
comments: false
---Git bash 中的一些 hexo 命令
hexo g
为在本地新生成页面,生成完之后可以hexo s
在本地看看效果hexo d
为把 public 文件夹中的内容推送到 github,可以加上参数-- message "<>"
指定 git commit 的信息。执行第一次之后会多出.deploy_git
文件夹,里面就是带版本控制的 public 文件夹(真正推送到 GitHub)hexo clean
清除 public 文件夹中历史生成的文件,不常用
至此,只需要把新的 markdown 文件放入
hexo/source/_posts
,图片可以放入hexo/source/images/
或theme/source/assets/images/
中以相对方式引用。然后运行上述命令生成推送。
一些可选插件
使用 npm install <plug-in name> --save
安装。
- hexo-filter-auto-spacing
自动在中英文间加上空格的插件(我喜欢手动)。
- hexo-image-lazyload
图片懒加载的插件。
- hexo-generator-sitemap
部署时自动创建 sitemap,方便 Google 抓取。
- hexo-math
重点说说这个,一个可以插入 MathJax 的插件,这样可以在文内优雅地使用 LaTex 公式。
安装完了在 _config.yml
配置一下,加上下面的内容:
1 | math: |
主要是将 source 换成 jsdelivr,默认的 cloudflare 经实践在局域网很多地方加载有问题。
还要干一件事是,这个插件显然是在 markdown 渲染到 html 以后才在页面中插入 MathJax 的脚本,然后加载 html 之后才完成替换。所以公式中大量的 _
很可能被渲染成了 <em></em>
,毕竟 markdown 语法中也有 _
(和 *
是一样的作用),用于标注斜体或粗体。所以我们要去掉对 _
的渲染,只保留 *
的用法。
hexo 默认的引擎是 marked,在 node_modules/marked
中,需要打开 marked.min.js
(ilb/marked.js
),搜索 em:
,应该会找到两处,删除掉正则表达式里面所有 _
的部分,例如 0.7.0 版是:
1 | var inline = { |
替换为下面的保存即可。
1 | var inline = { |
使用的时候行内公式使用 \\( equation \\)
,行间公式使用 $$ equation $$
。注意换行要用四个斜杆了 \\\\
,如果有中括号也要注意。
Amazon S3 + CloudFront 图床
总得需要一个放图片和视频等东西的地方,比较小的可以直接放到 GitHub 上,但是 repository 目前有 1GB 的限制,所以比较大的照片和视频和其它文件就放到了 Amazon S3,费用基本是看流量,目前大概 1GB = ¥1。
注册一个账号,国际的
创建一个 S3 储存桶,名称随意,填域名就好,
<username>.github.io
或者image.<custom-domain>
这样。在「设置 -> 权限 -> 存储桶策略」里面复制粘贴下面的内容,把
<bucket-name>
替换成刚才的,<username>
也要替换。
1 | { |
"Condition"
用来防盗链,这样只有通过之内的域名(HTTP Head)才能访问这个储存桶的文件。只适用于以 https://s3-ap-northeast-1.amazonaws.com/<bucket-name>/<filename>
访问的情况。
在「属性」页面,选择静态网站托管,索引文件填
index.html
,错误文档填error.html
,不必真的有这两个页面。这一步也可以不需要。这时候往这个存储桶里上传文件,就可以有一个链接了。当然,这个链接在大型局域网下访问会很缓慢,有的还打不开。下面加上一个 CDN 就会好不少,而且在大型局域网外也会改善。
打开 CloudFront Distribution 选择
Create
:Origin Domain Name
选择刚才 S3 Bucket 的名称Alternate Domain Names (CNAMEs)
有自定义域名就填,没有就空着Price Class
选择Use Only US, Canada, Europe and Asia
- 限制存储桶访问,创建新身份,并更新存储桶策略(授予读取权限),这样会自动在存储桶策略中的
"Statement"
中加入允许 CloudFront 访问的以下内容1
2
3
4
5
6
7
8
9{
"Sid": "2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXX"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<bucket-name>/*"
}
过一会 就会部署好,使用
cloudfront.net
的域名(或自定义的)访问即可。这样有个问题是使用这个域名速度非常快但是是没有防盗链的,需要配合 AWS WAF 解决。
OneDrive 图床
不得不说 CloudFront 的速度还是相当之快,即使是 HK 上线之前局域网内也是秒开。唯一的缺点就是费用还是需要一点的,尤其是图片很多的话。目前 AWS 还没有免费额度(一年试用之后)。
后来还是希望使用完全免费的平台,也不上域名之类的。所以我现在使用的是 OneDrive,被墙了,但是同 Flickr 一样,嵌入的图片是可以打开的。使用方法很简单,想办法上传之后,然后点击嵌入,复制链接即可使用(最好删掉链接 ?
及之后的内容,否则比如 GIF 会不动)。
如果说缺点,大概就是:
- 大局域网内不如 AWS 快
- 每张图片都需要手动点击嵌入,复制链接(AWS 的链接前面都是相同的,链接中只需改文件名,而 OneDrive 的链接都是乱的)
多台电脑之间同步
我大多数时间使用一台 Windows 的台式机,出门旅游过年回家等用 Mac。这部分得学习 Git,感觉这也是用 GitHub Pages 的好处,廖雪峰的 Git 教程我看就很不错且够用。
前提知识:
./.deploy_git/
如前所述,这个是真正推送到<username.github.io>
这个 repository 的文件夹,而且,每次hexo deploy
执行的都是 force push,意味着如果这个文件夹丢失,那么之前的 commit 也都会消失。把 theme 文件夹里可能有的 .git 文件夹删了,目录里不能同时有两个(.deploy_git 下也有一个,但是这个在 .gitignore 中被忽略了)。
新建一个 repository,称它为 backup repo(有人说用分支,但是现在 private repo 也免费了,而且还不会占一个 repo 1GB 的空间限制)。
针对 tranquilpeak 这个 theme:删掉 theme/.gitignore 里面的
assets
。在 Hexo 文件夹的 Git Bash 中
git init
->git add .
->git commit -m "<info>"
->git remote add origin git@github.com:<username>/<reponame>.git
->git push -u origin master
现在,除了 public 和 node_modules 之外的所有文件都备份到了 GitHub。前者通过
Hexo g
生成,后者npm install
安装,都是无需备份的。在新的电脑上,首先安装 Git、Node.js、Hexo,然后配置好 SSH Key,然后把刚才的 backup repo
clone
下来,再把<username.github.io>
这个 repoclone
到 hexo 文件夹内,文件夹名称改为.deploy_git
。最后在 hexo 和 theme 上分别npm install
。在 Windows 上有个很蠢的问题就是它可能不让用
.
开头作为文件(夹)名,需要 cmd 命令ren <dir_path> .deploy_git
【更新:Windows10 1903 已经解决了这个问题】之后需要在两台电脑切换时,只需在做了最新修改的一台电脑 push backup repo;然后在另一台 pull backup repo,如果执行过
hexo d
的话还要在.deploy_git
上也 pull。就完成了多台电脑的同步,且这样不会丢失 commit history。
更新 Hexo 的版本
更新升级意义不大,大版本再折腾吧。theme 直接下载新的 release,把 _config-theme.yml
和 assets
文件夹复制过去覆盖就好,当然前提是看下 _config-theme.yml
有没有大变化。
Hexo 可以修改 package.json
里面的版本,最新版本号可以 npm outdated
查看,然后 npm install
。
Terminal 配置代理,及 Homebrew 的安装(Mac)
在 ~/.zshrc
中添加以下两行
1 | alias proxy="export all_proxy=socks5://127.0.0.1:1080" |
之后只要在 Terminal 中输入 proxy
即可走 Shadowsocks 代理,注意端口不一定是 1080
,看下 SS 的设置。配置好之后 Homebrew 以及后面的 sass-node 等的安装应该都不需要额外配置了。
如果需要使用镜像安装 Homebrew,那么先将 https://raw.githubusercontent.com/Homebrew/install/master/install
保存为 install.rb
,然后修改其中的 BREW_REPO = "https://mirrors.ustc.edu.cn/brew.git".freeze
,再使用 /usr/bin/ruby ~/Desktop/install.rb
安装。应该会卡在
1 | ==> Tapping homebrew/core |
这时只需 git clone git://mirrors.ustc.edu.cn/homebrew-core.git/ /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core --depth=1
即可完成安装。最后可以按照 https://mirror.tuna.tsinghua.edu.cn/help/homebrew/ 的说明都换成清华源。