从JSON到接口文档,教你如何优雅生成组件API!

背景

最近在做一个组件库的项目,对第三方库进行二次封装并暴露自定义属性,每个组件都有一份默认数据的 JSON格式。如何根据默认数据生成组件 API 文档?本文将教你如何使用 json-to-ts、prettier、ShellJS、TypeDoc、fs-extra、ora、path 等 JS 库优雅生成接口文档。

方案

方案非常直接,只需要两步:

  1. JSON 转 TypeScript
  2. 通过 TypeScript 生成组件 API 文档

原本以为这个需求已经有现成的轮子,但找了一下午都没有找到,只能自己实现一个

准备工作

首先,我们需要安装以下依赖:

bash 复制代码
npm install json-to-ts prettier shelljs typedoc fs-extra ora path --save-dev

我们所有的脚本文件都用 ts 来写,这样可以避免很多 类型 和 引用 问题

生成 TypeScript 接口

我们可以使用 json-to-ts 库 将 JSON 数据转换为 TypeScript 接口。首先,创建一个名为 json-to-interface.ts 的文件,并编写以下代码:

typescript 复制代码
import * as jsonToTs from "json-to-ts";
import * as fs from "fs-extra";
import * as path from "path";
import prettier from "prettier";

// 获取目标文件夹下的定义的 默认数据文件
export const getTargetFiles = (targetPath) => {
  let components = [];

  const files = fs.readdirSync(targetPath);
  files.forEach((item, index) => {
    let stat = fs.statSync(`${targetPath}/` + item);

    let isBool = true;
    try {
      fs.statSync(`${targetPath}/` + item + "/defaultProps.ts");
    } catch (error) {
      isBool = false;
    }

    if (stat.isDirectory() === true && isBool) {
      components.push(item);
    }
  });

  return components;
};

const transform = () => {
   // 获取待处理的组件名. targetPath 为存放默认数据的文件夹路径
  let components = getTargetFiles(targetPath);

  // 开始处理组件
  components.forEach((name) => {
    console.log(`当前处理组件的 - ${name}`);

    const jsonFilePath = path.resolve(
      __dirname,
      `${targetPath}/${name}/defaultProps.ts`
    );
   
    // 获取数据
    const { defaultProps: json } = require(jsonFilePath);

    // 可以先对默认数据做一下前置处理
    // ...
    
    // 获取 interface 数据
    const interfaceData: string[] = JsonToTS(json, { rootName: "DefaultProps" });
    
    // 可以对生成的 interfaceData 进行自定义配置处理
    // ...

    // interface 文件路径
    let filePath = `${targetPath}/${name}/interface.ts`;
    filePath = path.resolve(__dirname, filePath);

    // 使用 Prettier 格式化代码
    const formatData = prettier.format(interfaceData, {
      singleQuote: true,
      parser: "typescript",
    });

    // 写 interface 文件
    fs.outputFileSync(filePath, formatData);
 });
}

这段代码首先从我们的目标文件夹中读取名为 defaultProps.ts默认数据 文件(json 格式),然后使用 json-to-ts 库将 JSON 数据转换为 TypeScript 接口,并将结果写入名为 interfaces.ts 的文件中。

由于 json-to-ts 提供的 api 较少,如果我们需要给生成的接口上添加 自定义的数据,可以通过遍历 interfaceData 来动态添加

typescript 复制代码
interfaceData.map(item => {
    if (item.includes("interface DefaultProps {")) {
      const linkName = item.split(" ")[1];
      return `
            /**
             * @module ${title}
             * @see 点击此处查看区块详细 props -> {@link ${linkName}}
             */
            ${item}
        `;
    }
    return item;
  })

生成的 interfaces.ts 内容如下

生成接口文档

我们可以使用 TypeDoc 库 将生成的 TypeScript 接口转换为 HTML 文档。创建一个名为 generate-doc.ts 的文件,并编写以下代码:

typescript 复制代码
// 从 json-to-interface.ts 中导出相关的方法和属性
...

const generateDoc = () => {
  // 获取 typeDoc 配置文件
  const typeDocConfigPath = path.resolve(__dirname, "../../typedoc.json");
  let configJson = require(typeDocConfigPath);

  /** 将待生成文档的组件地址,注入到 typeDoc 配置文件中
   * basePath、name、components:是在上个阶段【生成 TypeScript 接口】获取的
   */
  configJson["entryPoints"] = components.map(
    (name) => `.${basePath}/${name}/interface.ts`
  );

  // 格式化 json 代码
  configJson = prettier.format(JSON.stringify(configJson), { parser: "json" });

  // 更新 typeDoc 配置文件
  fs.writeFileSync(typeDocConfigPath, configJson);

  // 生成文档
  shell.exec("typedoc --tsconfig ./tsconfig.json");
}

最终生成的 typedoc.json 大概如下图:

json 复制代码
{
  "entryPoints": [
    "./src/components/AboutUs/interface.ts",
    "./src/components/Contact/interface.ts",
    ...
  ],
  "out": "demo-docs",
  "name": "demo 组件 api",
  "exclude": [
    "**/__tests__/**/*",
    "**/node_modules/**/*"
  ],
  "theme": "default",
  "excludeExternals": true,
  "excludePrivate": true,
  "excludeProtected": true,
  "skipErrorChecking": true,
  "disableSources": true,
  "readme": "./scripts/generate/readme.md"
}

修改 package.json 文件,添加以下脚本:

json 复制代码
"scripts": {
  "docs": "npx tsx ./generate-doc.ts",
}

然后,执行以下命令生成接口文档:

bash 复制代码
npm run docs

这将在项目根目录下生成一个名为 demo-docs 的文件夹,其中包含接口文档的 HTML 文件。

可以定制 文档首页 的显示内容,通过一份 readme.md 来定制

最后

通过 json-to-tsTypeDoc 两个组件库的配合,以及多项交互优化,让你轻松生成组件 API

相关推荐
Devil枫9 分钟前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦43 分钟前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子1 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山2 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享2 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
从兄3 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf4 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨4 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL4 小时前
npm入门教程1:npm简介
前端·npm·node.js
小白白一枚1115 小时前
css实现div被图片撑开
前端·css