“对项目进行配置化改造可以提高开发效率,让开发者将精力集中在业务开发中,减少琐碎重复工作对心情的影响。更重要的是,配置化可以减少因人工操作带来的失误,并且利于排查问题。”
上面正是我在对自己的项目进行改造后的感受。我维护了两个 Hexo 主题项目, hexo-theme-tranquility 和 hexo-theme-academic(未正式发布)。由于两个主题的测试用例重合度非常高,每次新增测试用例都得手动在两个主题上测试,很不方便。并且为了方便用户使用和查看示例,我想构建一个专门的演示网站对两个主题进行展示,并且希望每当我更新测试用的项目时,演示网站的两套主题都会自动更新部署。
于是考虑通过配置化利用一个博客资源同时部署若干主题,并通过 Github Actions 让两个主题更新后都自动部署,方便用户查看更新内容和测试示例。
最终实现的效果是这样的,建立测试项目 hexo-theme-test。每当该项目进行推送时,自动在网址 theme.hozen.site/tranquility 和 theme.hozen.site/academic 部署使用了主题 hexo-theme-tranquility 和 hexo-theme-academic 的网站。
简言之,需要解决两个问题,一个就是同一个博客资源部署多个主题,另一个是 Github Actions 的自动部署。下面分别介绍。
Hexo 多主题部署
Hexo 在 themes/
目录下可以存放多个主题文件,但只能通过
_config.yml
指定一个主题进行部署,并且部署到网站根目录。当修改主题后,之前生成的内容会被覆盖。我希望
themes/
目录下的主题都能部署,并且互不影响。
部署多个主题的解决方法很简单,只需要通过更改 _config.yml
的配置,修改主题的输出目录,使不同的主题使用不同的子目录即可。例如我要部署【致远】和【academic】两个主题时分别修改
_config.yml
的以下部分:
1 |
|
1 |
|
这样在两个 URL 下就输出了使用不同主题渲染的网站了。
配置分离
通过以上方法虽然解决了业务需求,但是由于每次部署主题都得去修改
_config.yml
文件。并且万一忘记修改,那么另一个主题网站就会被当前的主题所覆盖,很不方便。因此这里利用
Hexo 的配置融合机制。将两个主题不同的配置项分别放入配置文件:
_build.tranquility.yml
和 _build.academic.yml
中。通用的配置仍然放在 _config.yml
。
最后编写两个 scripts
命令来加载不同的配置文件:
1 |
|
这样我们就可以通过执行 npm run trqlt
和 npm run
acdmc
来在本地运行不同的主题,并通过执行
build-tranquility
和 build-academic
来构建不同的主题了。并且两个主题互不影响,构建后的文件分别放置在
public/tranquility
和 public/academic
下。
使用子模块管理两个主题
需要注意,由于这个博客网站只是为了测试和演示,其使用到的主题都是单独的项目,并且以后可能加入其他主题。所以需要使用
Git 的子模块 submodule 功能来管理模块。具体来说就是在该仓库下将 hooozen/hexo-theme-tranquility
和 hooozen/hexo-theme-academic
两个项目作为子模块分别导入到 themes/tranquility
和
themes/academic
目录下。这样做的好处是,可以在该仓库下直接对两个项目进行更新和维护,同时又保证了这两个项目的独立性。
有关 Git 子模块的使用方法,可以参考 Git 子模块 submodule 的使用
自动部署网站
Hexo 官网给出了利用 Github Actions 自动部署网站的示例,但并不能完全满足我的需求,主要有以下几点需要改进:
网页的生成依赖到了第三方软件 pandoc,Github Actions 的默认环境中没有该软件
需要部署两个主题网站到子目录下
需要移动 CNAME 文件到根目录
对于第 1 个问题,需要利用 Docker 来解决。第 2 和第 3 个问题增加相应的指令即可。
创建 Docker 镜像
创建具备 Node 和 Pandoc 环境的镜像,可以 Node 镜像为基础在其中安装 Pandoc 软件包。由于把项目生成和部署的操作在 Github Actions 中执行,因此 Docker 镜像中并不放入项目代码也不执行任何项目命令,只是创建运行环境。所以 Dockerfile 非常简单,如下:
1 |
|
使用以上 Dockerfile 创建镜像后,将该镜像上传到 Dockerhub 就能在 Github Actions 中拉取镜像并创建容器了。
编写 workflows 配置
准备好镜像后,只需要子啊 Github Actions 中使用该镜像创建容器,并执行相应的项目命令就能构建项目代码了,并使用相关的插件实现网站的自动部署。
首先在项目根目录下创建 .github/workflows/pages.yml
文件,然后编写以下内容:
1 |
|
在该配置文件中:
使用
container
项指定了上文中创建并上传的具备 Node 和 Pandoc 的 Docker 镜像。Github actions 在执行时会使用该镜像创建 Docker 容器,接下的操作都会在该容器中进行。使用
actions/cache@v3
检出项目主分支,然后使用actions/cache@v3
缓存node_modules
目录以提高构建速度。接下来执行
npm install
安装依赖,然后依次运行npm run build-tranduility
和npm run build-academic
来使用两个不同的主题构建页面。注意两个构建命令之间执行rm -f db.json
来清除 Hexo 的缓存文件。构建完成后,在
public
文件夹下会生成两个子目录tranquility
和academic
分别存放了两个主题的页面。由于我使用了自定义域名,因此使用
mv
命令将 CNAME 文件移动到public
目录下。最后使用
peaceiris/actions-gh-pages@v3
来将public
下所有的文件部署到 gh-pages 分支。
经过以上操作,每当我在 hexo-theme-test
项目中推送代码时,Github Actions
都会自动将更新内容使用两个主题分别部署在 theme.hozen.site/tranquility
和 theme.hozen.site/academic
上。
总结
- 对于 Node 项目不同环境和子项目的配置化,可以通过编写
scripts
命令和编写 Node 或者 Bash 脚本来读取配置文件实现。 - Github Actions 是对 Github 仓库进行自动化配置的好工具,有非常强大的功能。
- Docker 的应用对于跨平台的项目运行和部署非常方便。