前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >“注释”生成“VitePress文档网站”只需要“一行命令”!来试试!

“注释”生成“VitePress文档网站”只需要“一行命令”!来试试!

作者头像
luciozhang
发布2023-04-22 16:44:09
1.3K0
发布2023-04-22 16:44:09
举报
文章被收录于专栏:前端lucio

开门见山

先把工具掏出来。

jsdoc2vitepress

github

需求

你可能用过jsdoc,用代码里面的注释生成文档。但是苦于jsdoc生成的文档网页太不好看目录结构不好调整

你可能也用过VuePress或者VitePress。但是苦于手写Markdown文档太费时间

那有没有一种方案,可以直接用代码注释,生成vitepress构建的文档网页呢?

为什么不行?今天,作者封装了一个工具组件,满足你的需求!!

设计

我们大可不必从头撸起,只需要把jsdocVitePress巧妙结合一下。

实现思路

JavaScript注释->Markdown文档->VitePress站点

组件

这里面JavaScript注释->Markdown文档的部分,我们用到jsdoc2md这个组件来完成。

生成Markdown文件到指定目录后,我们希望不用修改VitePress的配置文件,就可以自动根据目录的结构,生成VitePress的侧边栏。这里我们用到作者的另一个组件vitepress-plugin-autobar

封装

根据泰斯勒定律,也叫复杂性守恒定律,每一个过程都有其固有的复杂性,存在一个临界点,到达临界点之后就不能再简化了,你只能将固有的复杂性从一个地方转移到另外一个地方。

为了方便使用,我们把现有的组件封装一下,把上面想法的复杂性留给自己,给使用者留下最简单易用的jsdoc2vitepress组件。

实现

初始化VitePress文档目录

期望的效果是:

代码语言:javascript
复制
jsdoc2vitepress init

初始化出下面的VitePress文档目录

代码语言:javascript
复制
.
├─ docs
│  ├─ .vitepress
│  │  └─ config.js
│  │  └─ jsdoc2vitepress.config.js
│  └─ index.md

这里就是一个简单的模板脚手架的功能,可以参考我们之前的一篇文章来实现具体的代码。

Node.js脚手架开发完全指南「TypeScript版」

下面是具体的代码实现。

代码语言:javascript
复制
// init-docs.ts
import ora from 'ora';
import fs from 'fs-extra';
import gitclone from 'git-clone/promise';
import path from 'path';

/**
 * @module init-docs
 * @description init docs directory
 */

/**
 * @exports initDocs "jsdoc2vitepress init" init docs directory
 */
export const initDocs = async () => {
  const loading = ora('Init docs directory');
  try {
    const templateGitUrl = 'https://github.com/luciozhang/jsdoc2vitepress-template.git';
    const docsDir = path.resolve(process.cwd(), 'docs');
    await gitclone(templateGitUrl, docsDir, { checkout: 'master', shallow: true });
    fs.removeSync(path.join(docsDir, '.git'));
    loading.succeed('Init docs directory success');
  } catch (error) {
    loading.fail(`Init docs directory fail: ${error}\nPlease delete local 'docs' directory and retry.`);
  }
};

jsdoc生成Markdown

这一步主要是读取源码,用jsdoc2md对源码注释生成Markdown文档。

我们直接用这个组件的代码作为示例,代码的目录结构是下面这样的

预期效果是生成下面的Markdown文档。

Markdown内容是注释生成的API文档。

jsdoc2md需要一个配置文件jsdoc2md.config.json。这里上一步初始化的模板已经生成了一个可用的配置文件,更多的配置内容,参考Configuring JSDoc with a configuration file

下面是具体代码实现。

代码语言:javascript
复制
// jsdoc-to-md.ts
import fs from 'fs-extra';
import path from 'path';
import jsdoc2md from 'jsdoc-to-markdown';
import ora from 'ora';

const configJ2VPath = path.resolve(process.cwd(), 'docs', '.vitepress', 'jsdoc2vitepress.config.json');
const configJ2MPath = path.resolve(process.cwd(), 'docs', '.vitepress', 'jsdoc2md.config.json');

/**
 * @module jsdoc-to-md
 * @description Generates Markdown API documentation from jsdoc annotated source code.
 */

/**
 * @exports jsdocToMd Generates Markdown
 * @returns {Promise} Return promise to check if generate success
 */
export const jsdocToMd = async () => {
  const loading = ora('Generates Markdown');
  try {
    const { markdownDirs } = await fs.readJSON(configJ2VPath);

    await Promise.all(markdownDirs.map(async (sourceObject: any) => {
      const { root, output, ingoreList } = sourceObject;
      await makeMarkDownForFiles(root, output, ingoreList);
    }));
    loading.succeed('Generates Markdown success');
  } catch (error) {
    loading.fail(`Generates Markdown fail${error}`);
  }
};

const makeMarkDownForFiles = async (root: string, output: string, ingoreList: Array<string>) => {
  const fileList = await fs.readdir(root);
  await Promise.all(fileList.map(async (fileName) => {
    if (ingoreList.indexOf(fileName) === -1) {
      await makeMarkDownDoc(fileName, root, output);
    }
  }));
};

const makeMarkDownDoc = async (sourceName: string, sourceRootPath: string, outputPath: string) => {
  let sourcePath = `${sourceRootPath}/${sourceName}`;
  const outputName = sourceName.replace('.js', '').replace('.ts', '');

  const loading = ora(`Generates Markdown for ${sourcePath}`);
  try {
    // 处理js文件的路径,需要区分是文件或目录,目录会将目录下所有文件生成为一个md
    const stat = fs.lstatSync(sourcePath);
    if (stat.isDirectory()) {
      sourcePath = `${sourcePath}/*`;
    }

    const mdStr = await jsdoc2md.render({
      'example-lang': 'javascript',
      files: path.resolve(process.cwd(), sourcePath),
      'name-format': 'backticks',
      'heading-depth': 2,
      'module-index-format': 'none',
      configure: path.resolve(process.cwd(), configJ2MPath),
    });
    if (mdStr) {
      fs.outputFile(path.resolve(process.cwd(), `${outputPath}/${outputName}.md`), mdStr);
      loading.succeed('Generates Markdown success in ' + `${outputPath}/${outputName}.md`);
    }
  } catch (error) {
    loading.fail(`Generates Markdown fail for ${sourcePath}`);
  }
};

Markdown生成Vitepress站点

有了Markdown文档,我们接下来就是简单的运行Vitepress框架,生成Vitepress文档站点了。

这里我们额外加一个优化,自动生成Vitepress的侧边栏配置,用到作者的另一个组件vitepress-plugin-autobar

这一步主要是用shell执行vitepress命令,具体代码如下。

代码语言:javascript
复制
//md-to-vitepress.ts
import shell from 'shelljs';
/**
 * @module md-to-vitepress
 * @description Generates VitePress API documentation from jsdoc annotated source code.
 */

/**
 * @exports startVitePress Run VitePress server
 * @returns {Promise} Return promise to check if run success
 */
export const startVitePress = async () => {
  shell.exec('node_modules/.bin//vitepress dev docs');
};

/**
 * @exports buildVitePress build VitePress server
 * @returns {Promise} Return promise to check if build success
 */
export const buildVitePress = async () => {
  shell.exec('node_modules/.bin/vitepress build docs');
};

整合命令行工具

最后,就只需要在入口文件,把上面封装的方法,整合成命令行工具了,具体代码如下

这里用到了commander库。

代码语言:javascript
复制
// index.ts
#!/usr/bin/env node

import { Command } from 'commander';
import { initDocs } from './init-docs';
import { jsdocToMd } from './jsdoc-to-md';
import { startVitePress, buildVitePress } from './md-to-vitepress';

const program = new Command();

program
  .name('jsdoc2vitepress')
  .description('Generates vitepress API documentation from jsdoc annotated source code.')
  .version('1.0.0');

program
  .command('init')
  .description('init vitepress directory.')
  .action(async () => {
    await initDocs();
  });

program
  .command('start')
  .description('Generates vitepress API documentation from jsdoc annotated source code and run Vitepress')
  .action(async () => {
    await jsdocToMd();
    await startVitePress();
  });

program
  .command('build')
  .description('Generates vitepress API documentation from jsdoc annotated source code and run Vitepress')
  .action(async () => {
    await jsdocToMd();
    await buildVitePress();
  });

program.parse();

最终效果

初始化文档,运行文档网站

代码语言:javascript
复制
jsdoc2vitepress init
jsdoc2vitepress start

控制台输出

文档网站

构造VitePress网站

代码语言:javascript
复制
jsdoc2vitepress build

控制台输出

构建结果

使用建议

这个工具最适合用于给组件库生成文档,建议配合CI/CD,在提交组件库代码的时候,触发构建文档和发布npm的流程,由代码注释生成文档并构建发布,从而确保组合库和文档的一致性。

来试试吧!

jsdoc2vitepress

github

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开门见山
  • 需求
  • 设计
    • 实现思路
      • 组件
        • 封装
        • 实现
          • 初始化VitePress文档目录
            • jsdoc生成Markdown
              • Markdown生成Vitepress站点
                • 整合命令行工具
                • 最终效果
                  • 初始化文档,运行文档网站
                    • 构造VitePress网站
                    • 使用建议
                    • 来试试吧!
                    相关产品与服务
                    命令行工具
                    腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档