或是出于跟风,或是为了简历能好看点,2020 年 2 月,在翻看了中文互联网大量的「免费个人网页搭建教程」后,我选择了 Hexo + Github Pages 的方案,找了一款看上去还不错的主题,搭建了自己的第一个博客网站。

很难量化我在这接近两年的时间里有了什么成长,我迎来了一学期的网课(甚至期末考试都是线上),见证了前所未有的生活方式的转变(从此社恐人可以合理戴口罩了),学习了更多的计算机专业课知识(虽然已经忘光),写了更多的汉字(我都不好意思说能叫文章),体验了一边在互联网企业 996 一边赶学期大作业 Deadline 的生活(然后现在推行「1075工作制」),准备考研又开始准备找工作,准备找工作又准备 Gap 去支教……

这之中大概还是有很多值得记录的吧,然而从结果上看我并没有留下什么,因此我也开始思考就我个人的情况而言,用时间轴将文章串联起来的博客,是否是个人网站最合适的载体。

你需要的怎样的个人网站?

知乎、简书、博客园、微信公众号……那些优秀或不那么优秀的写作平台已经有很多很多。而选择独立于这些大平台,去运营自己的个人网站,这件事多少带点理想主义色彩——个人网站缺乏稳定的流量来源,在国内更是需要备案等操作,虽然能免于平台审核的等待,但更多时候恐怕只是小圈子的孤芳自赏。

而我最早是为什么开始写文章的呢?虽然「nobody cares」,但我现在想想依然觉得有些不可思议,当时的自己为什么有勇气做这种事(顺带一提我突然想起了粉丝刚刚破一万时我是如何声情并茂地和舍友讲了一下午我是怎么涨粉的的黑历史,太尴尬了,现在我已经忘了当时他的脸上是怎样的神情)。

搭建个人网站则主要是为了寻找一种将所学知识归类展示的渠道,希望可以通过笔记避免知识的遗忘。从我之前在 Hexo 上发布的博客来看,我发布的内容以课程内容、软件技巧为主,这些内容一般有比较明确的分类和标签,比起瀑布流式的文章,更适合用树状的Docs进行整理,这也成了本次迁移到 Docusaurus 的主要动力。

Hexo 有哪些不适合你的地方?

在使用 Hexo 的过程中,我主要遇到了以下痛点(事实上很多痛点都是技术菜所导致的):

  • Node 版本问题:此前 Hexo 在 Node 14.x 以上版本运行时会存在兼容问题(我不清楚现在是否解决了),网上的资料通常是建议将 Node.js 降级至 12.x 版本使用。为此我不得不安装 nvm 管理电脑上不同的 Node 版本,每次写博客前还需要切换 Node 环境,在一定程度上打击了创作积极性。
  • 不够省心的客户端:体验过几个 Hexo 客户端,感觉界面和自己的期待有些差距,使用时也会遇到一些小问题,于是又回到了命令行创建新博客的方式。
  • 瀑布流式的文章组织方式:虽然 Hexo 提供了标签、分类等功能,但是没有进一步的层级关系,标签过多也不利于日后复盘。因此,文档式的知识库也许更符合我的需求。
  • 较高的主题定制门槛:我使用的是从 Github 上找的 Hexo 主题,作者主要使用 JQuery 开发,然而我在前端上学艺不精,只会站在 React、Vue 的肩膀上修修补补,似乎除了改改主题颜色就没有别的能做的事情了。
  • CI/CD 部署问题:之前创建博客时没有使用 CI/CD,每次更新 Github Pages 都需要经过「写博客 → 生成静态页面 → 上传到 Github」的过程,所以这次采用 Docusaurus 构建个人知识库时就用了自动部署。

Docusaurus 是什么?有哪些优势?

Docusaurus 是一款基于 React 构建的站点生成器,可用于构建文档网站、博客、营销页面(落地页)等。

  • Docusaurus 的文档和博客功能都是开箱即用的,背靠 Facebook 开源项目团队(现在应该叫 Meta ?),官方文档对于中文的支持也很友好,主要功能都能在文档上找到。
  • 支持在 Markdown 语法中嵌入 React 组件,此外还有丰富的插件库,比如能在线运行的代码执行器等,可以进一步丰富个人网站的功能。在这次的迁移过程中我就用 Infima 的 Note 组件美化了迁移信息。
  • Docusaurus 是一款 React 应用程序,对于曾在「软件工程」课上被 React + Typescript 折磨的我来说,我对于 React 语法比较熟悉,可以尝试增加自己所需的功能。
  • 颜值高:第一眼看上去感觉 Docs 很像 Gitbook,自身的配色我感觉也挺不错,之后可能会微调下标题字号。

当然,经过近一周的使用我也发现了一些小问题:

  • 标签功能并不好用:Docusaurus 会将标签按照首字母进行分类,英文标签还好,中文标签则每一个单字都会成为一个分类。
  • 暂时还没有评论功能:Docusaurus 支持添加文档搜索模块,但我还没找到类似 Gitalk 的评论插件(虽然这个功能也没啥必要)。
  • 同样缺乏 GUI:好在 Docusaurus 会自动根据 docs 下的目录树划分文档层级,便于建立个人知识库。博客则需要在标题中注明时间与题目,可能需要自己写一个简单的脚本。
  • 导航栏定制问题:Docusaurus 采用 Infima 的Navigation Bar 组件,通过注入的方式设定导航栏参数。原生导航栏定制自由度不高,好在可以放弃引入,自行编写导航栏(从「Docusaurus 站点展示 | Docusaurus 中文文档 | Docusaurus 中文网」里的源码学到的)。

目前 Docusaurus v2 还是 beta 版本,社区很活跃,看好这个工具的前景。

从 Hexo 迁移到 Docusaurus 需要几步?

忍不住讲起某个大象与冰箱的笑话,虽然我一直感觉这个笑话好冷。HexoDocusaurus 的 Front-matter 存在部分命名上的差异,好在它们都是用 YAML 格式组织的,因此我写了两个简单的 Ruby 脚本(Github 仓库地址),可以提取出原先在 Hexo 生成博文的时间戳、标题、标签、分类等信息,将其分别转换为 Docusaurus 格式的文档和博客 Markdown。

  1. #!/usr/bin/ruby
  2. require 'pathname'
  3. require 'tmpdir'
  4. require 'yaml'
  5. def copy_not_null_array(hexo_yaml_info, hexo_key, docusaurus_yaml_info, docusaurus_key)
  6. if hexo_yaml_info[hexo_key]
  7. if hexo_yaml_info[hexo_key].class != Array
  8. docusaurus_yaml_info[docusaurus_key] = [hexo_yaml_info[hexo_key]]
  9. else
  10. docusaurus_yaml_info[docusaurus_key] = hexo_yaml_info[hexo_key]
  11. end
  12. end
  13. end
  14. def parse_markdown_file(filepath)
  15. output_directory_name = "./output"
  16. text_all = File.read filepath.to_s
  17. # 分割博文的头部和正文
  18. begin_split = text_all.index('---')
  19. unless begin_split
  20. return
  21. end
  22. end_split = text_all.index('---', begin_split + 1)
  23. head = text_all[0, end_split]
  24. body = text_all[end_split + 4, text_all.size]
  25. # 读取YAML头部信息
  26. temp_filename = File.join(Dir.tmpdir, "yaml_head.temp")
  27. temp_file = File.new(temp_filename, "w")
  28. temp_file.puts head
  29. temp_file.close
  30. hexo_yaml_info = YAML.load_file(temp_filename)
  31. File.delete(temp_filename)
  32. # 迁移所需的YAML信息
  33. # - Docusaurus文章属性: https://www.docusaurus.cn/docs/blog#header-options
  34. blog_name = hexo_yaml_info['title'].gsub(/[()]/, '('=>'「', ')'=>'」')
  35. docusaurus_yaml_info = Hash.new
  36. docusaurus_yaml_info['authors'] = 'mondaycha' # 在authors.yml中完善信息
  37. # docusaurus_yaml_info['author_url'] = 'https://github.com/MondayCha'
  38. # docusaurus_yaml_info['author_image_url'] = 'https://github.com/MondayCha.png'
  39. # docusaurus_yaml_info['author_title'] = '我逐渐理解了一切(完全没理解)'
  40. docusaurus_yaml_info['title'] = blog_name
  41. docusaurus_yaml_info['date'] = hexo_yaml_info['date'].strftime("%Y-%m-%d %H:%M:%S")
  42. copy_not_null_array(hexo_yaml_info, 'tags', docusaurus_yaml_info, 'tags')
  43. copy_not_null_array(hexo_yaml_info, 'categories', docusaurus_yaml_info, 'keywords')
  44. if hexo_yaml_info['photos'] and hexo_yaml_info['photos'][0]
  45. docusaurus_yaml_info['image'] = hexo_yaml_info['photos'][0]
  46. end
  47. # 将新头部和正文写入文件
  48. unless File.directory? output_directory_name
  49. Dir.mkdir(output_directory_name, 755)
  50. end
  51. create_time = hexo_yaml_info['date'].strftime("%Y-%m-%d") # 时区有问题,待修复
  52. title = hexo_yaml_info['title']
  53. output_filename = File.join(output_directory_name, create_time << '-' << blog_name.gsub(' ','-') << '.md')
  54. if File.file? output_filename
  55. File.delete(output_filename)
  56. end
  57. output_file = File.open(output_filename, 'a+')
  58. output_file.puts docusaurus_yaml_info.to_yaml
  59. # 生成摘要,否则缩略页不忍直视
  60. truncate = "---\n<!--truncate-->"
  61. output_file.puts truncate
  62. output_file.puts body
  63. output_file.close
  64. end
  65. directory_name = "./"
  66. file_list = Pathname.new(directory_name).children.select { |c| c.to_s.match('.*.md$') }
  67. file_list.each do |filepath|
  68. puts filepath
  69. parse_markdown_file(filepath)
  70. end

将脚本放在 Hexo 目录下的 \source\_posts文件夹下,与此前创建的博文平级,之后运行脚本即可获得适用于 Docusaurus 的 .md文件。

从零开始的 Docusaurus 配置生活

1. 环境配置

以 Windows 系统为例,需求 Node.js 版本 ≥ 14,最好选择 Yarn 作为你的包管理工具。从官网下载 Node.js 的安装包并安装完成后,确保 Node.js 已经添加到了环境变量中:

  1. PS F:\FuckNPM\l1lBlog> node -v
  2. v16.13.0

使用自带的 npm 完成 Yarn 的安装,正如曾几何时 Edge 打开的第一个与最后一个网页就是 Chrome 下载页。

  1. npm install -global yarn
  2. yarn config set registry https://registry.npm.taobao.org/ # 使用淘宝维护的npm镜像源
  3. yarn config set proxy http://XX
  4. yarn config set https-proxy http://XX

2. 初始化网站

Docusaurus 已经提供了一个模板(或者说 Scaffold?),我在 Github 上也看到有人做的精简后的模板。如果你已经完成了 Node.js 和 Yarn 的安装,那么只需要几行命令就能很快启动网站:

  1. npx create-docusaurus@latest my-website classic
  2. cd my-website
  3. yarn start

部署完成后,如果 3000 端口没有被占用,那么访问 localhost:3000 就能看到提供的模板页面了。

3. 创作你的创作

如果你已经有 Hexo 博文,那么正如上一节,将博文的 Front-matter 转换后放入根目录下的blogdocs文件夹。可以参见官方文档中的说明,非常详细。

4. 最期待的 CI/CD 环节

我选择使用 Github Pages 进行部署,先参考「部署 | Docusaurus 中文文档 | Docusaurus 中文网」一节,修改docusaurus.config.jsmodule.exports部分,否则 Github Actions 会显示无权访问,因为你把网页部署到 Facebook 那里去了……

参考「部署 | Docusaurus 中文文档 | Docusaurus 中文网」一节进行 ssh key 的设置,由于我并非生成某个 Github 项目的文档页,而是生成 Github 的根博客,官方提供的documentation.yml代码并不能很好运行,在参考了其他项目后,我使用了如下配置文件:

  1. name: documentation
  2. on:
  3. push:
  4. branches: [documentation]
  5. jobs:
  6. deploy:
  7. runs-on: ubuntu-latest
  8. steps:
  9. # checkout && nodejs
  10. - uses: actions/checkout@v2
  11. - uses: actions/setup-node@v2
  12. with:
  13. node-version: '15'
  14. - run: yarn install && npm run build
  15. # delopy
  16. - uses: peaceiris/actions-gh-pages@v3
  17. with:
  18. github_token: ${{ secrets.GITHUB_TOKEN }}
  19. publish_dir: ./build

我的 Github 项目分支结构可以参考「MondayCha/MondayCha.github.io: MondayCha's blog, made with Docusaurus v2.

至此就完成了从 Hexo 到 Docusaurus 的迁移与部署工作了,如果说您有疑问的话也可以在评论区或 Github Issue 区留言,我有看到就会回复的。

个人网站迁移之旅:从博客到知识库,从 Hexo 到 Docusaurus的更多相关文章

  1. Ceph相关博客、网站(256篇OpenStack博客)

    官网文档: http://docs.ceph.com/docs/master/cephfs/ http://docs.ceph.com/docs/master/cephfs/createfs/   ( ...

  2. 个人博客搭建全记录(Hexo,Github)

    搭建过程主要借鉴小歪的博客 博客主题airclod Hexo,Github建站记录 1. 准备 Github账号 注册登陆Github 创建Repository,Repository Name就是Yo ...

  3. Hexo博客系列(三)-将Hexo v3.x个人博客发布到GitLab Pages

    [原文链接]:https://www.tecchen.xyz/blog-hexo-env-03.html 我的个人博客:https://www.tecchen.xyz,博文同步发布到博客园. 由于精力 ...

  4. node.js博客GitHub搭建(hexo)

    教程参考官网提供的: https://hexo.io/zh-cn/ 教程: https://hexo.io/zh-cn/docs/ 我的node.js环境: hexo博客全程采用markdown进行编 ...

  5. 在github pages网站下用jekyll制作博客教程

    https://www.jekyll.com.cn/ https://github.com/onevcat/vno-jekyll https://help.github.com/articles/us ...

  6. UVA10779 Collectors Problem 【迁移自洛谷博客】

    这是一道不错的练最大流建模的基础题. 这种题目审题是关键. Bob's friends will only exchange stickers with Bob, and they will give ...

  7. Uva10491 Cows and Cars 【迁移自洛谷博客】

    题目大意 假设有a头牛,b辆车(门的总数为a+b),你先选一个门,然后你最终选择前主持人会替你打开C扇有牛的门(不会打开你已经选择的门),问你要不要换门,输出"总是换门"的策略下, ...

  8. UVa1636 Headshot 【迁移自洛谷博客】

    说明:小蒟蒻hkk现在正在做一些概率的题目,由于这方面和数学还有点关系,所以需要一些数学的思维,也需要表述出来,如夏军所述"把自己给讲懂",所以写了些blog,主要为帮助自己理解. ...

  9. JSOI2018冬令营游记&总结(迁移自洛谷博客)

    游记 一开始在冬令营还没开始的时候,十分期待,殊不知每天都有一场浩劫在等着我. Day0 10:50出发,看见lbn同学发了一条说说,也随便发了一个. 然后在车上一直在睡觉,现在感觉挺后悔的,其实可以 ...

随机推荐

  1. C#并行编程:Parallel的使用

    前言:在C#的System.Threading.Tasks 命名空间中有一个静态的并行类:Parallel,封装了Task的使用,对于执行大量任务提供了非常简便的操作.下面对他的使用进行介绍. 本篇内 ...

  2. Windows内核开发-9-32位和64位的区别

    Windows内核开发-9-32位和64位的区别 32位的应用程序可以完美再64位的电脑上运行,而32位的内核驱动无法再64位的电脑上运行,或者64位的驱动无法在32位的应用程序上运行.这是为什么呢. ...

  3. NX 图标

    vector_on_curve   crosscut_zig_zag_with_lifts vector_along_curve   zlevel_zig add_new_sc   zlevel_zi ...

  4. Linux命令(二)

    1.cd命令 这是一个非常基本,也是大家经常需要使用的命令,它用于切换当前目录,它的参数是要切换到的目录的路径,可以是绝对路径,也可以是相对路径.如: cd /root/Docements # 切换到 ...

  5. Golang通脉之切片

    因为数组的长度是固定的并且数组长度属于类型的一部分,所以数组有很多的局限性. func arraySum(x [3]int) int{ sum := 0 for _, v := range x{ su ...

  6. 想要彻底搞懂大厂是如何实现Redis高可用的?看这篇文章就够了!(1.2W字,建议收藏)

    高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间. 假设系统一直能够提供服务,我们说系统的可用性是100%.如果 ...

  7. mysql的一些配置操作

    mysql的一些配置操作 一.背景 二.mysql配置 三.慢查询日志 1.命令行临时生效 2.配置文件修改永久生效 3.慢查询日志解释 4.mysqldumpdlow查看慢查询日志 四.查看索引为何 ...

  8. 关于QGIS的插件开发(C++)

    关于C++插件的开发材料较少,根据网上的指导,我采用了早期版本的插件模板生成的方法来创建QGIS的插件,其方法是从以前版本(2.18.25)里面拷贝插件模板的方法进行,具体的执行步骤为 1.拷贝文件 ...

  9. 单片机I/O口推挽与开漏输出详解(力荐)

    推挽输出:可以输出高,低电平,连接数字器件;推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止. 开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电 ...

  10. 不可错过的stm32单片机直流电机驱动与测速详解

    stm32直流电机驱动与测速 说实话就现在的市场应用中stm32已经占到了绝对住到的地位,51已经成为过去式,32的功能更加强大,虽然相应的难度有所增加,但是依然阻止不了大家学习32的脚步,不说大话了 ...