前言
项目正式版发布了,最近比较清闲,闲逛的时候看到rsshub这个库,想玩一下,但是rsshub文档里的接口太多了,自己手敲又嫌麻烦,突发奇想解析rsshub的文档自动生成所有文档出现的api给前端页面使用。
不是什么原因我的yarn和npm都装不了rsshub这个包,我是直接拉GitHub的rsshub下来用的,能装的可以直接安装,不行的也可以像我一样拉下来用,就是有点丑陋。
项目地址
效果图
没有特地去写样式,有部分接口有问题,可能获取不到数据
代码
首先第一步也是最核心的一步就是解析文档,提取有效信息,当然是用正则去解析对应的api名称,标题,path等,我定义了一个常量先声明这些正则规则。
const RegMap = {
Type: new RegExp(/\s#\s(.+)\s/g),
Content: new RegExp(
/\s##.+\s+###.+\s+()|(<\/Route>\s+###.+\s+)/g
),
Title: new RegExp(/\s##\s(.+)\s/g),
ChildTitle: new RegExp(/\s###(.+)/g),
Route: new RegExp(/(\)/g),
Example: new RegExp(/example="(\S+)"/g),
Path: new RegExp(/path="(\S+)"/g),
ParamsDesc: new RegExp(/paramsDesc="(.+)"/g),
};
解析文档内容,这里我是直接下载了文档的,你也可以去请求文档来解析,找有效信息的代码稍微有点low,解析之后生成接口具体的标题、path等信息的json文件
let type;
const data = await fs
.readFileSync(join(__dirname, `../../docs/${file}`))
.toString();
data.replace(RegMap.Type, (_, val) => (type = val));
const list = data.match(RegMap.Content);
if (!list) return;
const result = [];
for (let index = 0; index < list.length; index++) {
const content = list[index];
let title, childTitle, route, example, path, paramsDesc;
content.replace(RegMap.Title, (_, val) => (title = val));
content.replace(RegMap.ChildTitle, (_, val) => (childTitle = val));
content.replace(RegMap.Route, (_, val) => (route = val));
if (route) {
route.replace(RegMap.Example, (_, val) => (example = val));
route.replace(RegMap.Path, (_, val) => (path = val));
route.replace(RegMap.ParamsDesc, (_, val) => (paramsDesc = val));
}
if (title) {
result.push({
title,
children: [
{
title: childTitle,
example,
path,
paramsDesc,
},
],
});
} else {
const parent = getParent(result, index);
if (parent) {
parent.children.push({
title: childTitle,
example,
path,
paramsDesc,
});
}
}
}
fs.writeFileSync(`./api/${file}.json`, JSON.stringify({ type, result }));
读取生成的接口信息json文件。
const apiPath = join(__dirname, "../api");
const files = await fs.readdirSync(apiPath);
files.forEach(async (file) => {
const data = await fs.readFileSync(join(apiPath, file)).toString();
routeList.push(JSON.parse(data));
});
使用express创建服务,读取并处理接口json,配置对应的后端api,并向前端页面提供routeList,方便一会页面直接获取其他接口。
const express = require("express");
const RSSHub = require("./RSSHub/lib/pkg");
const app = express();
const createRoute = require("./utils/create-route");
function GetData(url) {
return new Promise((res, rej) => {
RSSHub.init({});
RSSHub.request(`https://rsshub.app${url}`).then(res).catch(rej);
});
}
app.use(express.static("./static"));
const list = [];
await createRoute(list);
const routeList = list
.map((v) => v.result)
.flat()
.map((v) => v.children)
.flat();
// 根据routeList配置api
routeList.forEach((route) => {
app.get(`/api${route.example}`, async function (req, res) {
const data = await GetData(route.example);
res.send(data.item);
});
});
// 给前端提供routeList,方便前端调用其他接口
app.get("/api/alldata", (req, res) => {
res.send(list);
});
app.listen(8088, () => {
console.log("http://localhost:8088 端口启动".green);
});
页面上使用axios发起请求,使用petite-vue快速铺数据
{{item.title}}
{{item.title}}