搭建 Docusaurus 应用
我在三月把这个网页迁移到了 Docusaurus。这篇博文总结了我的经历。
为什么要用 Docusaurus?
这个网站用 Vue 搭建的黑暗时期将被永远钉在GH pages 仓库的提交记录的耻辱柱上。
当然,我也不是在说 Vue 的不好——它很强大,强大到你基本可以用它搭任何东西。我正在开发的学校社团管理系统就用 Vue 做前端。问题大概出在我身上,因为我没多少时间从头造所有东西。
我一开始出于三个原因选择了 Vue。即使我一开始用 React,理由也大差不差:
- 我计划展示我的几个早期作品,包括 Todo list 和 Math editor,而它们都是用 Vue 做的。如果整个网站都是基于 Vue 的,我就可以把它们轻松作为模块导入。
- 那时候,我正好在学习 Vue-CLI,而建造个人网站就成为了我动手操作的最好机会。
- 我享受对页面设计的高控制度,精细到每个组件放在哪里,大小多少。
但问题也很快出现了。列举几个:
- Vue 对纯静态内容来说不够理想。它不开箱即用地支持 Markdown。就为了搭建个简单的博客单元,我就得把每篇文章编译成 HTML 组件,再把它们一个个导入——这其中又产生了不少垃圾代码。
- 我没法搭建自动部署。CI 总是失败,而官方文档也没帮多少忙,因为我用的 CI/CD 应用是 CircleCI。这不是 Vue 的问题,是我的问题。我只是希望有个模板,我可以直接抄来用,可惜对于 Vue 来说这不存在。
- 我在用户界面设计上经验不足。硬编码的 CSS 在电脑屏幕上看起来很好,但到手机屏幕上就乱套了。而且,Vuetify 这个 UI 框架用起来实在是太深奥了。
总地来说,我希望有个工具,可以用 30 分钟做点什么出来,而不是用 30 天把什么都做出来。Docusaurus 在这方面表现不错,可以实现敏捷开发。
我已经搭过两个 Docusaurus 应用了:我们的信息化社的主页,以及Baterock 服务器的主页。它们的技术栈一模一样,所以的确有我可以即刻搬来用的模式。
也许我不该把 Vue 和 Docusaurus 相比较,就像你不会把刀和叉相比,但我只是想给我迁移到 Docusaurus 找几个理由。它可以直接上传 Markdown 文件,也有可以用来插入其他 React 组件的 React API。然而,我的确得从头学 React,因为我一直用的是 Vue,而 Vue 和 React 之间的巨大差异也值得让我再写篇文章。(而那可能是个更值得引战的题目。在这场圣战中,我还是站在 Vue 的一边。)
我还是不知道 Docusaurus 是不是搭建个人网页最好的工具(比如我认识的几个人都用 WordPress),但我还是决定用我熟悉的工具。Docusaurus 最初的目的其实是为了给开源项目存储文档,所以才叫 "Doc"-usaurus。但它用来存储文章和博客看起来也不错。
搭建应用
我花了 800 字讲些有的没的。开始进入正题。要初始化一个 Docusaurus 项目,只需要:
$ npx @docusaurus/init@latest init personal-page classic
$ yarn install
$ yarn start
然后接下来就有很多个性化配置要做。Docusaurus 的占位内容散落在各处,要把它们都抓出来会花点时间。这个提交记录包括了要做的大部分工作。亦可以用这个检查表:
- 把所有的
/docs
和/blogs
下的文件移除,再添加一些真的东西。按照需求修改/sidebars.js
。 - 给网站选择一个主题色。我用了
#39cac4
,在简介中给出了原因。你可以用这个工具生成各种明暗色调,再把它们贴进/src/css/custom.css
。 - 给网站画个 logo。大多数人可能会用 GitHub 头像,或者放张照片,但我真的画了个 logo,然后它变成了我的新 GitHub 头像。如果你想,你也可以重画一遍首页上的“特色”图片。
- 逐行浏览
/docusaurus.config.js
,做必要的改动。 - 逐行浏览
/src/pages/index.js
,做必要的改动。 - 要启用 TypeScript 支持,在命令行运行
yarn add @docusaurus/module-type-aliases
,然后把下列文件添加到根目录:
/// <reference types="@docusaurus/module-type-aliases" />
- 对我来说必不可少。可以这么安装它:
$ yarn add rehype-katex
$ yarn add remark-math@3.0.1
然后添加配置内容:
const remarkMath = require('remark-math');
const rehypeKatex = require('rehype-katex');
module.exports = {
title: 'Joshua Chen',
...
stylesheets: [
{
href: 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css',
type: 'text/css',
integrity:
'sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X',
crossorigin: 'anonymous',
},
],
scripts: [
{
src: 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js',
integrity:
'sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4',
crossorigin: 'anonymous',
defer: true,
},
{
src: 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/mhchem.min.js',
integrity:
'sha384-5gCAXJ0ZgozlShOzzT0OWArn7yCPGWVIvgo+BAd8NUKbCmulrJiQuCVR9cHlPHeG',
crossorigin: 'anonymous',
defer: true,
},
],
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
remarkPlugins: [remarkMath],
rehypePlugins: [[rehypeKatex, { strict: false }]],
},
blog: {
remarkPlugins: [remarkMath],
rehypePlugins: [[rehypeKatex, { strict: false }]],
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
},
],
],
}
我从这里获得的灵感:https://docs.theochu.com/docusaurus/latex/。这可能不是最优雅的实现方法,但它能行。遗憾的是,我到现在也不能正确导入 mhchem
,所以 \ce{}
还是不能工作。
部署
下一步,我要设置 CI/CD。有现成的 CircleCI 配置文件可用。唯一的修改就是 git 密码以及 deploy-gh-pages
里的 environment
环境变量。在这里生成一个 Personal access token,只给它仓库控制权限,再把它贴进 CircleCI project settings > Environment Variables。然后就做好了。
现在我们的网站就已经填了不少内容了。下一步就是把 /docs/
和 /blog/
文件夹塞满,再用 React 多写几个页面。在未来的博文中,我计划讨论:
- 用 Bash 脚本自动化大规模文件处理;
- TypeScript vs JavaScript;
- React 组件 vs Vue 组件。
每个话题听起来都野心勃勃,可以以此写一整篇史诗。我会尝试把它们变得简练干脆的。