前言

最近接到了个需求,需要搭建一个内部wiki系统,用于记录规范、知识存档、问题排查等等,因此大致了解了下市面上常用的wiki工具,在GitBook、Wiki.js、MinDoc、DokuWiki之间犹豫了一下,最后还是选择了最轻量化的Docsify,基本能够满足现有的需求了。

因此今天就介绍一下Docsify的安装使用,以及一些常用的功能。

 

Docsify介绍

Docsify是一个快速生成文档网站的工具,实质是将.md文件(MarkDown文件)渲染成网页,不同于 GitBook、Hexo 的地方是它不会将.md文件生成静态的 .html 文件,所有转换工作都是在运行时执行。

Docsify是使用JavaScript开发的,只需要创建一个 index.html作为网页入口和参数配置,即可开始编写文档。

本文主要是介绍Docsify的自定义配置,md文档的编写不是本文的重点,MarkDown相关语法可以看这里

Docsify特性如下

  • 无需构建,写完文档直接发布
  • 文档修改后自动刷新页面
  • 容易使用并且轻量 (压缩后 约21kB)
  • 智能的全文搜索
  • 提供多套主题
  • 丰富的 API
  • 支持 Emoji
  • 支持嵌入式文件
  • 兼容 IE11
  • 支持服务端渲染 SSR 

 

Docsify安装

Docsify安装非常简单,首先到Node.js官网下载安装Node.js。

创建一个用于存放文档的文件夹,例如E:\Docsify。

打开CMD窗口,cd到E:\Docsify路径下。

然后通过NPM安装Docsify。

npm i docsify-cli -g

安装完毕后CMD中运行以下代码进行初始化

docsify init ./docs

其中./docs为docsify的工作路径,可以自由修改,运行完成后会自动生成这个工作路径文件夹,文件夹里会生成index.htmlREADME.md两个文件(还有个.nojekyll这个文件是用于阻止 GitHub Pages 忽略掉下划线开头的文件)。

其中index.html是Docsify的入口文件,README.md则是默认首页的内容。

最后在CMD中运行以下命令即可运行Docsify。

docsify serve docs

其中最后一个docs对应初始化时的工作路径,运行成功后,就可以通过浏览器访问127.0.0.1:3000,查看到默认的页面了。

如果想让Docsify运行在其他端口,可以通过以下方式修改端口号

docsify serve docs --port 80

 

Docsify的配置

Docsify的入口文件index.html中保存着Docsify的相关配置,首先看一下默认生成的内容

其中最关键的是window.$docsify,这个字典中就是Docsify的各种配置参数,包括后面如果要使用一些第三方插件时,插件的参数也需要写到window.$docsify中。

其次是id为app的div标签,这是默认的挂载元素,md文件渲染完后会挂载在id为app标签上。

这个默认标签是可以通过el参数修改的,例如

<div id="main"></div>
  <script>
    window.$docsify = {
      el: '#main',
    }
  </script>

下面介绍一些常用的配置参数

 

Loading提示

初始化时会显示 Loading… 内容,可以自定义提示信息。

<div id="app">加载中</div>

如果修改了默认绑定标签,就需要在绑定标签上加上data-app属性。

<div data-app id="main"></div>
  <script>
    window.$docsify = {
      el: '#main',
    }
  </script>

 

侧边栏标题设置

侧边栏为整个Docsify文档的目录,侧边栏顶部则是整个文档的标题,可以通过以下参数设置

window.$docsify = {
      name: 'Yumefx Wiki',
      nameLink: '/',
    }

效果如下

标题名称支持设置为html代码,可以灵活设置样式。

 

侧边栏网站图标

侧边栏中可以设置网页图标,并且可以使用CSS更改大小

window.$docsify = {
      logo: '/ico/icon.svg',
    }

 

GitHub Corner 挂件

可以在Docsify页面右上角生成一个GitHub Corner 挂件,点击即可跳转到设置的Github页面。

window.$docsify = {
      repo: 'https://github.com/yumefx/',
    }

效果如下

 

目录最大层级

Docsify是一个md文档渲染器,默认情况下会抓取md文件中所有标题并根据层级生成侧边栏目录,通过下面的参数可以配置最大层级,默认为6。

window.$docsify = {
      maxLevel: '4',
    }

 

隐藏侧边栏

功能就是隐藏侧边栏目录,默认为显示状态,并且侧边栏左下角有按钮可以收起或展开侧边栏,所以一般用不到这个功能

window.$docsify = {
      hideSidebar: true,
    }

 

自动跳转页首

默认切换页面后不会自动跳转到页首,可修改此参数在切换页面后自动跳转到页面顶部,更符合直觉

window.$docsify = {
      auto2top: true,
    }

 

首页文件加载路径

默认情况下,README.md为首页文件,如果想使用其他文件路径,可以添加此参数实现。

window.$docsify = {
      homePage: 'home.md',
    }

 

文档加载的根路径

默认情况下,文档加载的根路径就是index.html所在的路径,如果需要修改的话,可以添加此参数设置,可以是相对路径、网络路径,甚至可以将路径指到其他仓库

window.$docsify = {
      basePath: 'https://raw.githubusercontent.com/ryanmcdermott/clean-code-javascript/master/',
    }

 

封面页

如果需要使用Docsify官方文档同款封面页的话,可以添加coverpage参数并设置,默认开启后封面页文件为_coverpage.md,可修改

window.$docsify = {
      coverpage: true,
      coverpage: 'cover.md', //自定义封面文件
    }

 

更换主题色

默认的主体色是绿色,如果想要更换其他颜色可以添加以下配置参数

window.$docsify = {
      themeColor: '#3F51B5',
    }

效果如下

 

执行脚本

有时候会需要Docsify执行我们自定义的一些js脚本,可以通过以下方式执行md文件里的第一个script标签脚本。

window.$docsify = {
      executeScript: true;,
    }
### 自定义脚本

<script>
  console.log(2333)
</script>

如果要执行的是外链脚本,那么需要引入 external-script 插件

 

其他一些参数,例如relativePath(链接使用相对路径)、alias(定义路由规则)、noEmoji(禁用emoji表情解析)、externalLinkTarget(外部链接的打开方式)、notFoundPage(自定义404页面)、requestHeaders(设置请求资源的请求头)等等,因篇幅有限就不详细说了,可以去官方文档查看。

 

语法使用

前面说过Docsify支持常用的Markdown语法,这里着重说一下Docsify特有的语法。

 

嵌入文件

markdown语法本身支持图片的嵌入,而Docsify在此基础上进行了扩展,可以嵌入音频、视频等媒体,甚至可以引用md文件、嵌入代码块、嵌入网页(iframe)等等。

嵌入的格式如下:

[filename](media path ':include')

嵌入的类型是通过文件后缀自动识别的,这是目前支持的类型:

  • iframe .html.htm
  • markdown .markdown.md
  • audio .mp3
  • video .mp4.ogg
  • code other file extension

也可以通过type参数强制设置嵌入类型,例如下面的案例

# 文件嵌入示例

### 图片嵌入

![雀魂图片](img/majsoul.jpg)

### 音频嵌入

[HELLO](audio/HELLO.mp3 ':include :type=audio controls')

### 视频嵌入

[巨人](video/Titan.mp4 ':include :type=video controls width=100%')

### 代码块嵌入

[logging代码块](config.py ':include :type=code :fragment=demo')

### md嵌入

[readme](README.md ':include :type=markdown')

### 网页嵌入

[虚幻5帮助](https://docs.unrealengine.com/5.0/zh-CN/ ':include :type=iframe width=100% height=800px')



效果如下

其中,嵌入音频、视频、和网页时,实质就是转化成了html的媒体标签,因此可以通过添加标签属性控制宽高等外观。

而在插入代码块时,要截取部分代码进行展示时,可以在该块代码前后加入/// [demo]或者### [demo],其中的标志位demo可以换成其他字符,只要和fragment属性的值对应即可。

 

除此以外,Docsify还扩展了Markdown的语法,可以实现普通提示、强调内容、Github任务列表等特殊语法,并且由于最终是渲染成html页面进行展示的,因此可以将语法配合标签属性、CSS样式甚至JS代码,实现很多自定义的效果,这里篇幅有限就不一一演示了。

 

多页文档

Docsify可以很容易地创建和管理多页文档,原理和多级路由的网站类似,不同的链接地址对应不同的md文件。

文档的首页为/#/,默认对应docs根目录下的README.md(可以通过homepage参数修改默认的md文件名),那么对于docs/about/这个链接地址来说,对应的是docs根目录下about文件夹内的README.md;而docs/about这个链接地址,对应的则是docs根目录下的about.md

显然,末尾为/代表了文件夹名,末尾为字符代表了文件名,这与网站的路由设置是相同的。

例如下面的文件结构

.
└── docs
    ├── README.md
    ├── guide.md
    └── zh-cn
        ├── README.md
        └── guide.md

对应的访问页面如下

docs/README.md        => http://domain.com
docs/guide.md         => http://domain.com/guide
docs/zh-cn/README.md  => http://domain.com/zh-cn/
docs/zh-cn/guide.md   => http://domain.com/zh-cn/guide

因此,如果有大量文档需要分级管理,完全可以先将文档整理放进多级文件夹,再根据文件夹路径得到多级路由路径,最后生成侧边栏或者导航栏目录,方便查询和跳转。

 

侧边栏目录

Docsify默认情况下会根据当前md文档的标题层级自动生成侧边栏目录,但对于多页文档来说,往往会需要让侧边栏目录包含所有文档的层级和目录,从而方便跳转查看,这种时候就需要自定义侧边栏。

使用自定义侧边栏需要配置以下参数

window.$docsify = {
      loadSidebar: true,
    }

接着创建_sidebar.md文件,内容如下

* [首页](zh-cn/)
* [指南](zh-cn/guide)

最后效果如下

两个目录分别对应不同的md文件,但是可以发现,md文件内的标题目录没有了,这里需要再加上下面这个配置参数,设置一下子目录的层级。

window.$docsify = {
      subMaxLevel: 2,
    }

效果如下

这样,一个包含文件层级和标题层级的侧边栏目录就完成了。

如果不希望某个标题出现在侧边拦目录中时,可以在该标题栏后方添加<!-- {docsify-ignore} -->,例如

# Getting Started

## Header <!-- {docsify-ignore} -->

如果要忽略该md文件内所有标题,可以在页面的第一个标题后方加上<!-- {docsify-ignore-all} -->

这样就可以精简侧边栏目录,实现更加高效的查询。

 

多层级文档的侧边栏目录

首先,在_sidebar.md文件内,通过缩进就可以简单地设置层级,例如下面这种

* [入门](learn/)
  * [第一天](learn/day1/)
    * [第一课](learn/day1/class1)
    * [第二课](learn/day1/class2)
  * [第二天](learn/day2/)
    * [第一课](learn/day2/class1)
* [其他](orther/)
  * [指南](orther/guide)

效果如下

对于规模比较小的文档系统足够使用了,但是对于复杂多样的文档系统来说,最好是每个文件夹放一类的文档,让每个文件夹层级都有自己的独立侧边栏。

这当然可以实现,_sidebar.md的加载逻辑是从每层目录下获取文件,如果当前目录不存在该文件则获取上一级目录的_sidebar.md。例如当前路径为 /zh-cn/pages 则从 /zh-cn/_sidebar.md 获取自定义侧边栏,如果不存在则从 /_sidebar.md 获取。

因此可以在每一个文件夹目录生成一个_sidebar.md,里面的层级信息只包含本文件夹目录内的内容。

而不同文件夹目录之间的跳转,则可以通过导航栏实现。

 

导航栏

导航栏指的是Docsify页面右上角的菜单栏,一般用于在多类文档间跳转,或者作为一个更加简略的目录使用。

例如Docsify的官方帮助文档页面,就使用导航栏作了语言的切换功能,点击不同选项就可以跳转到不同语言的文档的首页,而每种语言的文档则有自己独立的侧边栏目录。

导航栏的设置也很简单,添加以下配置参数

window.$docsify = {
      loadNavbar: true,
    }

和自定义侧边栏方式类似,自定义导航栏也需要创建一个_navbar.md文件,其中的格式也和侧边栏类似,例如。

* [入门](learn/)
  * [第一天](learn/day1/)
  * [第二天](learn/day2/)
* [其他](orther/)
  * [指南](orther/guide)

得到的效果如下

有了导航栏和侧边栏的配合,复杂文档的目录管理和层级跳转就可以很方便的实现了。

 

实用插件

Docsify支持很多插件,并且也开放了API可以方便开发者去开发新的插件。

插件的使用方式很简单,直接在index.html内通过script标签引用js脚本就行,如果插件需要配置参数,就加入到window.$docsify内即可。

我整理了一些常用的插件,可以参考使用。

 

全文搜索

Docsify的目录只有跳转功能,没有搜索的功能,因此这个全文搜索插件可以说是必备插件,它会根据当前页面上的超链接获取文档内容,在 localStorage 内建立文档索引。默认过期时间为一天,也可以通过配置参数自己设定需要缓存的文件列表或者配置过期时间。

加载插件后Docsify页面左上角会显示搜索框,搜索到的结果可以快速进行跳转,效果如下

 

图片缩放

在文档中插入的图片,很多时候需要放大观看细节,这时就可以使用这个图片缩放插件,这样只要点击文档中的图片就可以全页面放大显示了。

 

字数统计和阅读进度条

加上字数统计阅读进度条这两个功能,会让文档更像博客文章,虽然没有什么大的作用,不过我很喜欢。

 

代码语法高亮

docsify内置的代码高亮工具是 Prism。Prism 默认支持的语言如下:

  • Markup – markup, html, xml, svg, mathml, ssml, atom, rss
  • CSS – css
  • C-like – clike
  • JavaScript – javascript, js

可以通过CDN引用相应的语法文件,从而实现其他语言的语法高亮显示,其中连Maya的Mel Script和3dsMax的Max Script以及HLSL等的语法文件都有,足够满足需求了。

而要让Docsify正确显示代码高亮,还应该在代码块开头处声明语言的种类,例如

```html
  <!-- index.html -->
  <div data-app id="main">加载中</div>

  <script>
    window.$docsify = {
      el: '#main'
    }
  </script>
```

 

代码复制

添加代码复制插件后,可以在代码块右上角生成一个按钮,点按即可复制代码块内的代码,免去鼠标划选的繁琐。

 

评论功能

Docsify毕竟只是文档渲染,没有本地的数据库,因此没有评论功能,但可以通过Disqus或者Gitalk插件实现评论功能,

只不过都需要账号注册和联网使用,内网环境下是不能使用的。

 

更多的功能插件可以在这里查看。

 

总结

Docsify作为一个轻量化的文档管理系统,功能比较简洁,使用也很简单,但缺少后台管理、账号系统、权限控制、评论等功能,因此只适合搭建公共查询类的简易wiki系统,例如公司内部规范、API接口文档、软件使用说明等等。

如果需要其他复杂的功能,还是选择功能更强大的wiki平台才行。


认识自己的无知,
是认识世界的最可靠的办法。

《随笔集》
——蒙田