好久不见!经过许久的折腾以后,终于闲下功夫来复盘一下博客如何部署起来的了!话不多说,这就进入主题!
选择博客主题和架构
作为一个主要承担内容输出的部分,我首先在自行开发和成熟博客框架上进行了趋于中间化的选择。成熟的框架,如WordPress,固然可以完整提供博客所具有的全部功能,但是略显笨重,且对于本来空间就不大的云服务器更是一种考验。如果全部自己撰写的话,又会陷入到维护成本过高的问题。各种小部件的适配和样式的维护,都是一件很痛苦的事情。由此看来,静态博客生成器是一个不错的选择。
GitHub上有很多成熟的静态博客生成器,如Hexo、Jekyll、Hugo等等。进行了一番对比后,我最终选择了Hexo 和Hexo-next 主题。Hexo本体是基于Node.js的,我可以专心使用Markdown书写内容,而由一些hexo终端命令来渲染成所需的静态文档。而且,经过对一些GitHub仓库的浏览,我发现Hexo的主题和插件也是非常丰富的,可以满足我对于博客的基本需求。
主题安装与配置
Hexo的文档很清楚,我可以直接通过npm命令来安装Hexo本体,并安装Hexo next主题:
npm install hexo-cli -g
npm install hexo-theme-next
安装完成后,博客根目录下会出现两种yml配置文件,一个是
_config.yml
,称为Hexo配置文件;一个是_config.next.yml
,称为主题配置文件。接下来就需要对这两个文件进行深一步配置。Hexo配置文件的进一步配置
首先是基本信息的填写,如博客标题、副标题、描述、关键词、作者、语言、时区等等。所有这些配置都将写入HTML的
meta
标签中,以便搜索引擎更好的索引博客。title: 随心记 # 标题
subtitle: 展现安全态度 # 副标题
# 浏览器标签页显示的标题会是 title - subtitle 的形式
description: # 站点介绍
keywords: # 关键词
author: # 作者
language: zh-CN # 所用语言,中国大陆为zh-CN
timezone: Asia/Shanghai # 时区,中国大陆网站最好设置为上海时区
我们安装的主题是hexo next主题,要在主配置文件(
_config.yml
)中写入主题的名称:theme: next
以上步骤结束,我们就可以通过
hexo s
命令来启动本地服务器,通过localhost:4000
来预览博客的样子了。但是,我们还需要对主题配置文件进行进一步配置。next主题配置文件的进一步配置
我所安装的Hexo已经是5.0版本以后了,官方推荐使用替代配置文件
_config.next.yml
来进行主题配置,以防止更新时被覆盖。首先是博客主题(scheme),NexT提供了4种主题(
Muse
、Mist
、Pisces
和Gemini
),我直接选择了默认主题Muse
,可能我个人对这个也没啥大要求吧,哪天可以改改试试其他的。scheme: Muse
然后是暗黑模式,这可以通过
darkmode
来设置。我并没有改变这个选项,感觉这个主题应该还是提供一个按钮,供用户切换比较好。darkmode: true
接下来是站点Favicon,是浏览器标签页上会显示的小图标,需要在
favicon
下进行设置,并引用相关图片资源文件。目前本站还没有进行这样的设置,以后会加上。favicon:
small: /images/favicon-16x16-next.png
medium: /images/favicon-32x32-next.png
apple_touch_icon: /images/apple-touch-icon-next.png
safari_pinned_tab: /images/logo.svg
有关博客文章的版权声明,鉴于本博客大多以分享为主,我沿用了主题提供的CC4.0配置,意味着放开了共享和演绎(虽然我的文章一般没啥人看就是了qwq)。这个选项的配置效果决定了文章底部的版权声明显示。
creative_commons:
license: by-nc-sa
sidebar: false
post: true
language:
为了优化SEO,OpenGraph当然是必须配置的。这里参考hexo的配置文档配置了一些项目。
open_graph:
enable: true
options:
# 配置twitter_id、twitter_profile等
目录设置需要在
menu
选项下进行配置,其配置分为Key
、link
和icon
三部分。其中:
-
Key
是目录项的名称,大小写敏感。除了home
和archive
以外,其他类型都需要在source
文件夹下手动创建文件夹和对应的index.md
文件 -
link
是目录项的链接,是链接到本站的相对路径,在实际测试时发现也可以写站外的绝对路径 -
icon
是目录项的Font Awesome图标名,可以在这里找到 -
link
和icon
之间用||
分隔
menu:
home: / || fa fa-home
about: https://www.jason0743.space/#/about || fa fa-user
tags: /tags/ || fa fa-tags
categories: /categories/ || fa fa-th
archives: /archives/ || fa fa-archive
sitemap: /sitemap.xml || fa fa-sitemap
menu
下还可以配置sub-menu
,其配置和menu
类似,但是本站没必要配置这个,就不写了。另外,在
menu_settings
还可以配置使用badges
或者icons
。badges: true
会显示文章、类别和标签的数量。默认的icons: true
会在menu
项前显示图标。侧边栏
博客中难免需要显示一些个人相关的社交平台联系链接。这些链接可以通过
social
配置项进行配置。它的格式与上述 menu 类似,但是指定的链接必须是绝对链接。social:
GitHub: https://github.com/<xxx> || fab fa-github
Twitter: https://twitter.com/<xxx> || fab fa-twitter
Facebook: https://www.facebook.com/<xxx> || fab fa-facebook
Instagram: https://www.instagram.com/<xxx> || fab fa-instagram
通过
social_icons
配置项可以进行进一步配置,如是否启用(enabled
)、是否只显示图标不显示描述(icons_only
)、是否显示过渡动画(transition
)等。中国常见的社交平台对应的 Fontawesome 图标名称总结如下:
社交平台名称 Fontawesome 图标名称 知乎 fab fa-zhihu 微博 fab fa-weibo 微信 fab fa-weixin fab fa-qq 抖音 fab fa-douyin 人人 fab fa-renren B站 fab fa-bilibili 对于单个博客文章,
Table of Contents(TOC)
是非常必要的,它可以显示你的文章的大致结构。可以通过toc
配置项进行启用和禁用。我的配置如下:toc:
enable: true
number: true
wrap: true
expand_all: true
max_depth: 6
侧边栏所展现的个人头像可以通过
avatar
来进行配置,NexT 主题还支持使用rounded
属性设置圆形头像,rotated
属性支持鼠标悬停时旋转头像。页脚
以下配置需要在
footer
选项下进行配置。备案信息
众所周知,开在中国大陆的站点都需要备案,而备案信息是需要在页脚显示的。这里可以通过
beian
配置项进行配置,如下:beian:
enable: true
icp: 京ICP备xxxxxxxx
gongan_id:
gongan_num:
gongan_icon_url:
建站时间
一般建站的时候,总会往页脚加入开站时间,类似于
2020-2023
这样的。默认情况下,NexT 主题会显示当前年份,可以通过since
配置项手动显示建站起始时间。footer:
since: 2020 # 年份,一般表示建站时间
页脚图标
页脚图标会显示在年份和版权信息之间,往往是一个红心图标。可以通过
icon
选项做更多自定义配置,如修改图标名称、修改图标颜色、使图标动起来等。版权信息
版权信息显示在页脚图标右侧,由
copyright
配置中的内容指定,如果未指定,则使用 Hexo 配置文件中的author
配置项。生成平台信息
在默认情况下,NexT 主题会在页脚显示
Powered by Hexo & Next.xxx
,表示生成器和主题,可以通过powered
配置项进行更改。我觉得留着也没什么问题,就没改。域名配置
根据GitHub相关配置文档和Hexo文档,需要在项目根目录下创建一个
CNAME
文件,里面写入你的域名,如example.com
。由于hexo部署时相当于把整个source文件夹复制到一个新的分支,故这个CNAME
文件需要创建在source/
文件夹下。在Hexo侧,需要在主配置文件
_config.yml
中配合作这样的设置,以正确加载脚本及相关资源文件:url: https://blog.jason0743.space/
root: /
其中 URL 项需要填写自己的自定义网址。我是使用了blog作为三级域名,所以在URL处填写的是整个网址,后面以斜杠
/
为结尾,而root就是网页的根目录。如果今后需要将博客部署在子目录中(像
https://example.com/child/
这样),就需要在 url 中带上子目录,在root项填写带有两边斜杠的子目录名(对于https://example.com/child/
这里就需要设置为/child/
)。现代网页的地址末尾已经不一定需要 html 后缀了,甚至,主页的
index
字样我们也可以不需要(虽然实际上Hexo还是生成了它)。把这两个配置为false
即可做到这一点。pretty_urls:
trailing_index: false
trailing_html: false
启用资源文件夹
我的博客项目中会有很多图片,把它们都放在
source/images
文件夹中则会显得非常拥挤且不好管理。Hexo 提供了一种资源文件夹的概念,它可以在创建的新文章同级目录自动创建一个同名文件夹,然后使用相对路径插件来引入这些资源。在主配置文件
_config.yml
中,将这个选项设为true
即可启用该功能。post_asset_folder: true
撰写文章时,使用这个语法插入即可,其中slug处要填写文件名:
{% asset_path slug %}
{% asset_img slug [title] %}
{% asset_link slug [title] %}
安装插件
评论显示
静态站并没有“后端”这个概念,传统的评论系统该怎么实现呢?我们可以借助一些插件来实现。
我在这里的选择是 Waline,比起之前的Valine来说,更加安全,但配置起来需要一定时间。它需要同时考虑到server和client的部署问题。
服务端配置
首先是LeanCloud端数据库的配置,注册账号和创建应用的过程就不赘述了(作为普通白嫖用户当然要选择开发版),然后到左侧的设置→应用凭证中,记下AppID、AppKey和MasterKey,以后要用到。
接下来使用Vercel进行服务端部署,如果没有账户的话,可以直接使用GitHub账号登录。然后点击Waline文档中的Vercel部署按钮或直接访问这个仓库的README.md文件。
接下来会基于一个简单的模板创建Git仓库,作为 GitHub 常驻用户肯定时要选择GitHub的,如果有别的平台也可以点击别的平台按钮创建。
项目创建成功后,进入到控制台中,从上方的“Settings”中进入项目设置,然后点击左侧的“Environment Variables”,进入环境变量配置,建立三个环境变量
LEAN_ID
、LEAN_KEY
、LEAN_MASTER_KEY
,分别对应上一步在LeanCloud获得的AppID、AppKey和MasterKey。然后点击顶部的“Deployments”进入部署页面,选择最近一次部署,点击“Redeploy“使得刚才的环境变量生效。部署好后就可以回到主页点击”Visit“访问服务端了。
其界面大致是这样的
如果需要加入域名(vercel默认域名实在有些丑),则依然需要进入设置页中,这次需要进入”Domains”中,输入需要绑定的域名并点击“Add”添加域名,然后在服务商处加入CNAME解析记录,其值为
cname.vercel-dns.com
,之后就可以用自己的域名来访问评论系统和管理端了。立即访问管理端(
<url>/ui/register
)进行注册,注册成功后,以后就可以通过<url>/ui
管理评论了。
<url>
为vercel域名设置中所列出的域名,项目新建的默认值一般为<project-name>.vercel.app
客户端配置
客户端需要进行样式导入和代码注入,对于hexo-next来说,像下面这样安装插件并加以配置即可。
npm install @waline/hexo-next
然后在主题配置文件
_config.next.yml
中加入以下内容:waline:
enable: true
serverURL:
libUrl:
cssUrl:
locale:
placeholder:
commentCount: true
pageview: true
emoji:
- https://unpkg.com/@waline/emojis@1.0.1/weibo
- https://unpkg.com/@waline/emojis@1.0.1/alus
- https://unpkg.com/@waline/emojis@1.0.1/bilibili
- https://unpkg.com/@waline/emojis@1.0.1/qq
- https://unpkg.com/@waline/emojis@1.0.1/tieba
- https://unpkg.com/@waline/emojis@1.0.1/tw-emoji
meta:
- nick
- link
requiredMeta:
- nick
lang: zh-CN
wordLimit: 0
login: enable
pageSize: 10
首先当然要启用该插件(
enable:true
)。然后需要设置serverURL
为刚才部署的服务端地址,如果使用了自定义域名的话,这里就需要填写自定义域名。语言当然设置为zh-CN
,我也启用了pageview
和commentCount
两个功能,显示文章的阅读统计和评论数量,配置效果如下:视频/音乐嵌入
博客如果只有静态的文字和图片的话,也未免太单调了吧!如果能适时地嵌入一些其他网站或自己上传的资源,就更好了。我选择的是 mmedia 插件,因为它目前支持较广,而且使用也比较方便。
针对hexo,只需要安装 hexo-tag-mmedia 插件即可,安装方法如下:
npm install hexo-tag-mmedia --save
然后在
_config.yml
下采用作者推荐的默认设置即可:mmedia:
audio:
default:
video:
default:
aplayer:
js: https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.js
css: https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.css
default:
contents:
meting:
js: https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js
api:
default:
dplayer:
js: https://cdn.jsdelivr.net/npm/dplayer@1/dist/DPlayer.min.js
hls_js: https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js
dash_js: https://cdn.jsdelivr.net/npm/dashjs/dist/dash.all.min.js
shaka_dash_js: https://cdn.jsdelivr.net/npm/shaka-player/dist/shaka-player.compiled.js
flv_js: https://cdn.jsdelivr.net/npm/flv.js/dist/flv.min.js
webtorrent_js: https://cdn.jsdelivr.net/npm/webtorrent/webtorrent.min.js
default:
contents:
bilibili:
default:
page: 1
danmaku: true
allowfullscreen: allowfullscreen
sandbox: allow-top-navigation allow-same-origin allow-forms allow-scripts allow-popups
width: 100%
max_width: 850px
margin: auto
xigua:
default:
autoplay: false
startTime: 0
allowfullscreen: allowfullscreen
sandbox: allow-top-navigation allow-same-origin allow-forms allow-scripts allow-popups
width: 100%
max_width: 850px
margin: auto
在使用上,假如要嵌入一个B站的视频,只需要使用这个简单语法:
{% mmedia "bilibili" "bvid:BV<xxxxx>" %}
即可,其中第一个参数是要引用的视频网站名称,第二个参数是要引用的视频id,以冒号或者等号分隔都可以。
如果要嵌入音乐播放列表,则需要采用其中的MetingJS标签形式。
{% mmedia "meting" "server=<netease|tencent|kugou|xiami|baidu>" "type=<song|playlist|album|search|artist>" %}
其支持的平台其实已经能够涵盖常见的用途了。如果以上几种不够用,还有最后的 Audio 和 Video 参数打底,它可以支持上传自有资源,插入原生的标签。
Markdown渲染器配置
Hexo默认搭配的渲染器是
hexo-renderer-marked
,其支持的渲染格式有限,所以我重新使用了hexo-renderer-markdown-it
,它支持更多的解析和渲染格式,如GFM和Commonmark等,还支持插件。在安装它之前,需要卸载 Hexo 默认自带的渲染器。
npm uninstall hexo-renderer-marked --save
然后再安装
hexo-renderer-markdown-it
。npm install hexo-renderer-markdown-it --save
它的配置在
_config.yml
中,直接使用默认的简单配置即可。markdown:
preset: default
render:
html: true
xhtmlOut: false
langPrefix: language-
breaks: true
linkify: true
typographer: true
quotes: “”‘’
enable_rules:
disable_rules:
plugins:
- markdown-it-abbr
- markdown-it-footnote
- markdown-it-ins
- markdown-it-sub
- markdown-it-sup
anchors:
level: 2
collisionSuffix:
permalink: false
permalinkClass: header-anchor
permalinkSide: left
permalinkSymbol: ¶
case: 0
separator: -
其实我最需要的是脚注(
markdown-it-footnote
)功能,这个语法可以用来写一些参考文献,或者是一些引用的资料。部署到GitHub
由于将博客放到云服务器上操作过程过于繁琐(万一域名失效了还得四处拷贝搬运,并且配置域名HTTPS啥的也是不少麻烦),我选择使用 GitHub Pages 功能来托管我的内容。GitHub Pages 是 GitHub 提供的一个静态网页托管服务,可以将静态网页托管到 GitHub 上,然后通过
username.github.io
的形式来访问。这样做的好处是,我可以将博客的源码和静态网页内容分开,而且可以通过 GitHub Actions 来实现自动化部署。建立仓库
在GitHub上建立一个新的仓库,并做好初始化,稍后我们会将博客的源码推送到这个仓库上。
本地的博客文件夹中,现在应该已经是这样的结构:
+--+
|---scaffolds
|---draft.md
|---page.md
|---post.md
|---source
|---_drafts
|
|---_posts
|
|---categories
|---index.md
|---tags
|---index.md
|---CNAME
|---_config.next.yml
|---_config.yml
|---package.json
|---package-lock.json
|....在这个文件夹下运行
git init
,之后再把这个分支推送到仓库中。目前,我的博客全部源码内容都在
main
分支上,而博客的静态网页内容则在gh-pages
分支上。这样做的好处是,我可以在main
分支上进行博客的编辑和维护,而gh-pages
分支则可以作为一个单独的静态网页仓库,用于部署到GitHub Pages上。使用GitHub Actions全自动化部署过程
Hexo 本身其实也有提供 deploy 命令用于部署仓库,但是这个命令每次都要手动执行,稍微有点不太方便。故我选择了尝试使用 GitHub Actions 来实现自动化部署。
GitHub Actions 是处于 git 仓库中
.github/workflows
文件夹下的一个 yml 配置文件。其记载了在什么样的条件下,自动执行什么样的操作。我们的文件是这样的:
name: publish-webpage
on:
push:
branches:
- main
jobs:
publish-webpage:
runs-on: ubuntu-latest
if: github.event.repository.owner.id == github.event.sender.id
steps:
- name: Checkout source
uses: actions/checkout@v3
with:
ref: main
- name: Setup Node.js
uses: actions/setup-node@v3