CocaColf

庭前桃李满,院外小径芳

分析文件夹生成文档页面

2021-04-13


背景

    最近小组在做 eslint 相关的升级改造,同时我们需要搭建一个平台,其内容为文档和一些好坏写法的代码展示等。

    为了让日后平台的维护者更好的维护文档,或者说只需要编写或删除文档,而不用修改代码,因此需要将文档自动化处理,和代码分离。

    由于在内网开发的我也不好截图,但是其效果和 Vue 官网这个效果基本一致:点击顶部某个导航栏,页面左侧为目录层级,右侧为文档信息。

效果

build时处理文档

    首先有两个约定:

    这个平台技术栈为 ViteVue

markdown to vue

    我们需要把 md 文档当成 Vue 组件渲染在页面上,因此配置一下 vite.config.js

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import Markdown from 'vite-plugin-md';

export default defineConfig({
    plugins: [
        vue({
            include: [/\.vue$/, /\.md$/],
        }),
        Markdown({
            markdownItSetup(md) {
                md.use(require('markdown-it-anchor'));
                md.use(require('markdown-it-prism'));
            },
        }),
    ],
});

编写脚本,build时处理文档

    我的思路如下:

    生成目录信息没有什么的难度:

    其中 文档名.json 内容示例如下,它表示的是左侧的目录层级关系,用于提供给左侧目录组件渲染目录:

// title为显示在左侧的目录标题
// child 为markdown中的标题
// path为该文档的路由
[{
    "title": "基础",
    "path": "",
    "child": [
        {
            "title": "介绍",
            "path": "/docs/test/jichu/jieshao.md",
            "child": [
                "介绍",
                "标题2",
                "标题3"
            ]
        },
        {
            "title": "安装",
            "path": "/docs/test/jichu/anzhuang.md",
            "child": [
                "安装",
                "标题2",
                "标题3"
            ]
        }
    ]
},
{
    "title": "深入",
    "path": "",
    "child": [
        {
            "title": "原理",
            "path": "/docs/test/shenru/yuanli.md",
            "child": [
                "原理",
                "标题2",
                "标题3"
            ]
        }
    ]
}]

    docsRouter.json示例如下:

// pathForRouter为路由
// path为某markdown文档的路径
[{
    "pathForRouter": "/docs/test/shenru/yuanli.md",
    "path": "/docs/test/深入/原理.md",
    "content": "这里是文档的内容"
}]

    然后在路由配置文件里,写一个小函数将原有的路由配置和现在生成的路由进行合并。文档路由的 component 配置为 import(/docs/test/深入/原理.md) 即可,其余的就交给 Vite 了。

    这里有两个细节:

    如果生成的路由是中文的话,比如 /docs/test/深入/原理.md,那么当你刷新当前路由时,会发现当前页面白屏了。这是因为浏览器会对中文进行编码处理 /docs/test/%E6%B7%B1%E5%85%A5/%E5%8E%9F%E7%90%86.md,因此刷新时,Vite 找不到编码后的这个路由导致找不到组件。

    生成路由信息文件时,顺便将文件内容也放入 json 中,是为了做前端搜索功能。你可以在 Vue 官网上 ctrl+k 体验一下搜索功能,实现效果基本是照它来的。不过Vue 官网的搜索是后端搜索的,我这里做的搜索功能是前端搜索。想必你猜到了,就是将搜索框内的搜索字符串在 docsRouter.json 中进行字符串搜索,因此我可以非常方便的一并将搜索结果对应的文档路由也获取到!因此做结果跳转就非常方便了。

业务代码中使用文档

    build 时,已经将所有信息都生成且处理好了,因此在某个页面中使用就很简单了方便了。比如现在 QA.vue 是一个文档展示页面:

// QA.vue

<template>
    <side-toc :tocData="tocValue" />
    <router-view />
</template>

<script lang="ts">
import { defineComponent } from "vue";

// 这里在导入生成的文档目录数据
import testDoc from '@/toc/test.json';

// 这是左侧目录组件
import SideToc from '@/components/SideToc.vue';

export default defineComponent({
    components: {
      SideToc
    },

    setup() {
        return {
            tocValue: []
        }
    }
});
</script>

Comments: