docsify,专为喜欢折腾的你。
使用体验
五一回家只带了公司笔记本,没什么娱乐软件,所以闲时刷了下 Github,发现一个 TIL(things I learn) 项目挺好的,于是 clone 下来做了一个自己的项目,这是我的 TIL 记录。
TIL 本意是记录自己学到的知识点。实际工作中会经常遇到问题并解决问题,长期以来并没有刻意记录,有些问题单凭记忆会在一段时间后忘记。
原项目中是依赖 Gitbook 做的文本渲染,按照我几年前的使用经历来看,Gitbook不算好用,并且在国内访问速度堪忧,所以我在这里选择了 docsify。
docsify 是一个类似 Gitbook 将 Markdown 文件选染成 HTML 页面的工具。当然也有一定差别,Gitbook 是提前编译成 HTML 静态页面,而 docsify 是请求时渲染。在使用上来看,docsify 的速度更快,也更简单一些,可自定义的配置非常多,适用于喜欢自己动手的开发者。
docsify 功能非常丰富,不过基本界面样式比较简单。
值得吐槽的是右上角repo角标太大了,和navbar菜单并在一起太丑陋了。
其他的一些插件,比如 「edit on github」 与 「字数插件」 会将正文内容往下挤,也很别扭。
官方文档里没有浅色模式与深色模式的灵活适配,只单一支持了浅色或深色主题,也就是说只能选择一种。
如果想同时支持浅色和深色,目前有两个方法:
- 有一个第三方主题插件,docsify darklight theme,安装即用,提供一个按钮手动切换,不过问题是仍然是按钮将正文内容往下挤压。我添加了一段JS方法,强制将按钮移到左侧sidebar。
- 自定义css,支持跟随系统深色模式,自动切换。实现方式类似我的blog,目前还没有时间开发。
开始构建
首先需要本地具备 node 和 npm 环境,选择最新的稳定版本即可。
安装 docsify-cli:
1 | npm install -g docsify-cli |
创建 Git 仓库,并且初始化 docsify:
1 | mkdir docsify-demo && cd docsify-demo |
这之后会自动创建出 docs 目录,其中会有一个 index.html
文件。
可以本地预览了:
1 | docsify serve docs |
然后,可以编辑 index.html
:
1 | window.$docsify = { |
可以在 docs 目录下创建这些文件:
- 一个空的
.nojekyll
文件,用于阻止 Github Page 忽略下划线开头的文件; _sidebar.md
文件,自定义左侧边栏目录;_navbar.md
文件,自定义右上角菜单栏。
可以安装 docsify-tool 依赖,我只用它来自动生成 _sidebar.md
内容:
1 | npm i -g docsify-tools |
docsify-auto-sidebar
会将指定 docs 目录下所有 Markdown 文件识别为目录内容,所以会将 _navbar.md
也将到目录里,我写了一个 Git pre-commit hook 来阻止这个动作。
在项目根目录,vim .git/hooks/pre-commit
,填入:
1 | docsify-auto-sidebar -d docs |
评论系统
docsify 支持 Disqus 和 Gitalk 两种评论系统。Disqus 在国内不太好用,所以我选择试试 Gitalk。
按照 docsify 的文档,很简单的使用上了 Gitalk 评论,但是在使用中发现满满的都是坑。
我这里主要问题是某些文章加载评论时报错 Error: Validation Failed
。
Gitalk 依托于 Github issue 存在,并且使用 issue label 和文章一一关联,issue label 有个限制是字符串长度需不超过 50。
然而 docsify 默认和 Gitalk 的集成,创建 issue 时使用的 label 是当前页面的 location.href
,也即是 URL 全文,这也太容易超过 50 了吧🥲。
在 Gitalk 文档中,也有说明 id 属性,默认使用 location.href
:
id
String
Default:
location.href
.页面的唯一标识。长度必须小于50。
在网上找到的解决方案,是手动设置 id 属性,对 href 做一次 md5,固定到 32 位。看起来很不错,引用了一个 md5 库之后,很简单搞定了。然而实际应用发现 docsify 切换页面时,路由经常没有自动刷新,导致各种奇奇怪怪的gitalk初始化问题,然后创建出的 issue 烂七八糟,而且经常在 A 页面写的评论在 B 页面可以加载出来。我猜测还是路由回调的问题,但我看不懂源码,没法解决。
然后在 Github 找了一些使用 docsify 写的项目文档,发现一个 l-hammer/You-need-to-know-css,效果很好并且评论没有问题。
读了这个项目的实现,发现没有依赖 docsify 对 Gitalk 的集成,直接引入的 Gitalk 依赖,并且在路由回调中初始化 gitalk 实例。
大概实现如下:
1 | gitalkConfig = { |
最后效果是这样,label 使用的是 location.hash 的尾部按 /
分割后的最后一段内容,其实就是每个 Markdown 文件名,到这一步已经很容易控制不超过 50 位长度了。
主题定制
darklight
使用docsify darklight theme,按照文档说明,非常简单。
在 index.html
头部添加:
1 | <link |
在底部添加:
1 | <script |
如果对默认的按钮展示位置满意,那可以到此结束了,下面是我的改动,将按钮移动到左侧边栏:
下载 darklight 的 Javascript 源码,放到项目里,可以命名为 theme.js
,移除远程引用,添加本地引用:
1 | <script src="theme.js"></script> |
然后修改 theme.js
的一处方法,这里的 afterEach
是 docsify 路由变化完成后的回调函数,主题原生的写法就是在 e
前面简单添加一个 div 块,这也是按钮将正文内容向下挤压的原因。添加 else 分支是因为这块代码在每次路由变化后都会执行,我们需要让它只在第一次加载页面时创建按钮 div。
1 | e.afterEach((function (e, o) { |
源码是编译过的,为了避免找不到在哪,这里是我改过的 theme.js 下载地址。
由于没有深入阅读 docsify 的主要源码,不确定这处方法怎么直接改动,所以在外面另外写了一处脚本作为后置处理,将按钮 append 到侧边栏的 DOM 下。在 index.html
中,添加一段 script:
1 | <script> |
如果觉得侧边栏问题太挤,可以再调整下样式:
1 | <style> |
prefers-color-scheme
prefers-color-scheme
是 CSS media feature 对黑暗模式的支持,详细文档在此。
按照我的博客的做法,只需设计下黑暗模式的背景颜色、字体颜色、代码块颜色、超链接颜色,基本效果就有了。
细节待开发…