Skip to content

Commit

Permalink
chore: 🎉 初始化 auto sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
shanyuhai123 committed Dec 25, 2019
0 parents commit 0f96b83
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 0 deletions.
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Vuepress Plugin Auto Sidebar

## 介绍(Introduction)

这是为 vuepress 自动生成侧边栏的插件。



### 1. 注意事项

若想要使用该插件,需要固定 docs 下路径(虽然在计划适配更多的情况,也添加了 `mode` 参数用于后期扩展,但在近两个月暂无计划)。



## 安装(Install)

```bash
npm i vuepress-plugin-auto-sidebar -D
```



## 使用(Usage)

```js
// 修改 docs/.vuepress/config.js

module.exports = {
// 引入插件(import plugins)
plugins: [
// 更多方式可参考(more use methods can refer to the documentation):
// https://v1.vuepress.vuejs.org/zh/plugin/using-a-plugin.html
"vuepress-plugin-auto-sidebar": {} // 可参考下方的 “可选项”
],
// 配置 sidebar()
themeConfig: {
sidebar: require('./sidebar.js'), // 这是默认情况,当然你也可以自定义路径和文件名。(This is the default, of course you can also customize the path and filename.)
}
}
```



## 可选项(Optional)

| 属性名称(key) | 类型(type) | 预设值(default) | 说明(description) |
| :-------------- | :----------: | :---------------: | :------------------------------- |
| mode | String | default | 可选的模式,当前仅支持 default。 |
| dest | String | .vuepress | 输出 sidebar 的路径。 |
| filename | String | sidebar | 输出 sidebar 的文件名。 |

37 changes: 37 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const fs = require("fs");
const path = require("path");
const { filterRootMarkdowns, filterDepthOneMarkdowns, filterDepthTwoMarkdowns, addDepthOne, addDepthTwo, genSidebar, genRoute } = require("./lib/utils");
const sidebarOptions = require("./lib/options");

const OPTIONAL_MODE = ['default']; // 待补充

module.exports = (options, ctx) => ({
name: "vuepress-plugin-auto-sidebar",
async ready() {
try {
const mergeOptions = Object.assign({}, sidebarOptions, options);
const { sourceDir, pages } = ctx;

// 映射 pages
const mapPages = pages.map(page => ({
path: page.path,
split: page.path.split("/").slice(1) // 移除多余的空格
})).filter(filterRootMarkdowns);

const depthOnePages = addDepthOne(mapPages.filter(filterDepthOneMarkdowns));
const depthTwoPages = addDepthTwo(mapPages.filter(filterDepthTwoMarkdowns));

let depthTwoPagesSidebar = Object.create(null);
const depthOnePagesSidebar = depthOnePages.reduce((acc, cur) => (acc[genRoute(cur.name)] = genSidebar(cur.name, cur.children), acc), {});
depthTwoPages.forEach(group => group.children.reduce((acc, cur) => (acc[genRoute(group.name, cur.name)] = genSidebar(cur.name, cur.children), acc), depthTwoPagesSidebar));
const SIDEBAR = Object.assign({}, depthOnePagesSidebar, depthTwoPagesSidebar);

// 处理输出
const filename = mergeOptions.filename.endsWith(".js") ? mergeOptions.filename : mergeOptions.filename + ".js";
await fs.writeFileSync(path.resolve(sourceDir, mergeOptions.dest, filename), `module.exports = ${JSON.stringify(SIDEBAR)}`);

} catch (ex) {
console.log(ex);
}
}
});
5 changes: 5 additions & 0 deletions lib/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
mode: "default", // 模式
dest: ".vuepress", // 暴露 sidebar 的路径
filename: 'sidebar'
}
62 changes: 62 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const filterRootMarkdowns = page => page.split.length !== 1; // 过滤 docs 目录下的 md 文件
const filterDepthOneMarkdowns = page => page.split.length === 2; // 筛选出深度为 1 的 md 文件
const filterDepthTwoMarkdowns = page => page.split.length === 3; // 筛选出深度为 2 的 md 文件

const addDepthOne = pages => pages.reduce((acc = [], cur) => {
const name = cur.split[0];
const filename = cur.split[1];
const findCur = acc.find(p => p.name === name);

if (findCur) {
findCur.children.push(filename);
} else {
acc.push({
name,
children: [filename]
});
}

return acc;
}, []);

const addDepthTwo = pages => pages.reduce((acc = [], cur) => {
const name = cur.split[0];
const sub = cur.split[1];
const filename = cur.split[2];
const findCur = acc.find(p => p.name === name);

if (findCur) {
const findSub = findCur.children.find(p => p.name === sub);

findSub ? findSub.children.push(filename) : findCur.children.push({ name: sub, children: [filename] })
} else {
acc.push({
name,
children: [{ name: sub, children: [filename] }]
});
}

return acc;
}, []);

const genSidebar = (title, children = [''], collapsable = false, sidebarDepth = 1) => ([{
title,
collapsable,
sidebarDepth,
children
}]);

const genRoute = (...names) => {
const joins = names.join("/");
return `${joins.startsWith("/") ? '' : '/'}${joins}${joins.endsWith("/") ? '' : '/'}`;
}

module.exports = {
filterRootMarkdowns,
filterDepthOneMarkdowns,
filterDepthTwoMarkdowns,
addDepthOne,
addDepthTwo,
genSidebar,
genRoute
}
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "vuepress-plugin-auto-sidebar",
"version": "0.0.1",
"description": "A vuepress plugin for generate sidebar",
"keywords": ["vuepress", "auto-sidebar", "sidebar"],
"main": "index.js",
"author": "shanyuhai123",
"license": "MIT"
}

0 comments on commit 0f96b83

Please sign in to comment.