解析Markdown文件生成React组件文档
前言
最近做的项目使用了微前端框架single-spa。
对于这类微前端框架而言,通常有个utility应用,也就是公共应用,里面是各个子应用之间可以共用的一些公共组件或者方法。
对于一个团队而言,项目中公共组件和方法的使用难点不在于封装不在于技术,很多时候在于团队内部成员是否都能了解这些组件,以避免重复开发,从而提升团队效率。
如果是团队比较小,人员比较稳定的项目组可能还好点,对于团队比较大,人员流动较快的团队,这些通用组件和方法往往就被人遗忘在角落,很难再得到有效利用。
因为我所在的项目还在开发初期,并且是新入职也想去熟悉一下当前项目中的一些通用组件和方法,所以我自己特意开发了一个文档应用去解决这个问题。
技术方案选型
对于一个面向Ant Design编程的咸鱼而言,这个文档应用肯定是往这个方向做。
目标是能做成Ant Design的组件文档那样好用,既能很快看清组件的使用效果,也能快速复制示例代码。
有了目标之后,很快选定了两个技术方案
- StoryBook方案
- 自己开发解析markdown文件的文档应用
StoryBook是市面上一款比较流行的构建UI组件和文档的库,功能很强大。
但是这个库如果要应用到我们项目的团队存在以下问题:
- 英文文档,有学习成本
- 引入single-spa的utility应用很麻烦
- 对于构建在utility应用中的组件,需要在StoryBook中再写一遍,容易不同步
- 对于通用方法可能不支持
尤其是第三点特别存在问题,团队成员大都是业务开发,有交付压力,不是在github上为爱发电的开源贡献者。
他们是否有意愿在utility应用中写了一遍组件代码后,又专门跑到这个StoryBook中再写一道?
如果组件代码修改后,StoryBook这边没修改,这种不同步很容易导致开发人员明明按照文档使用组件,但是组件就是报错,挫败感很强。
联系到现实,我已经预想到如果走这个方案,一个月内这个玩意就会名存实亡,成为形式主义的存在,在三个月后成为大家都不愿提起的垃圾了。
所以有了第二个方案的诞生:自己开发解析markdown文件的文档应用。
这个方案并不是我凭空想象出来的,而是在前公司中就有这么一个内部应用,组件开发人员自己编写markdown文件,最终生成组件文档,并且应用本身可以解析markdown文件中的代码部分,从而在组件文档中生成对应的组件示例。
彼时我只是一个组件开发人员,并不是这个文档应用的实现人员,所以也不知道其技术原理。
但是前公司这个应用让我知道了这么玩行得通,当时作为组件开发人员,接受和使用这个应用异常轻松,只要会写markdown就行了,没有学习成本。而且使用这种方式,控制权掌握在自己手中,更容易和自己的团队项目有效结合起来。
基本原理
虽然这个文档应用是我一个人花了两天的时间独立完成,但是花的是工作时间,完成后也是公司内部项目,所以这个文档应用我没法开源出来。
不过我可以告诉大家一个主要思路和步骤,想必复现出来也并不困难。
第一步让我们搞定这个项目的框架。
因为需要引入single-spa的utility应用,所以框架我直接用的是single-spa的基座,并且项目内含一个子应用用于展示文档。而utility应用直接引入线上开发环境的utility应用,避免团队成员重复书写组件代码,也解决了文档和实际应用不同步的问题。
通过这一步,我们解决了StoryBook方案中的痛点2和痛点3。
第二步我们需要载入markdown文件。
这一步肯定是通过webpack的加载器来做处理,这些加载器有的比较强大,可以直接将markdown文件转换为html。但是我并没有选择这种,而是直接用的raw-loader,将我们的markdown文件转换为字符串载入。
代码大致如下,这个比较简单,就不说了。
module.exports = {
module: {
rules: [
{
test: /\.md$/,
use: 'raw-loader'
}
]
}
}
第三步我们需要解析markdown文件生成文档,并解析其中的React组件,生成组件示例。
解析markdown文件转换为html文档,实际上有个比较强大的库,叫Showdown。
而我所用到的库react-showdown则是对Showdown的进一步封装,可以借助一个react组件将markdown和包含在markdown文件中的react组件渲染成html。
下面是它的一个官方示例:
import React from 'react';
import MarkdownView from 'react-showdown';
export default function App() {
const markdown = `
# Welcome to React Showdown :+1:
To get started, edit the markdown in \`example/src/App.tsx\`.
| Column 1 | Column 2 |
|----------|----------|
| A1 | B1 |
| A2 | B2 |
`;
return (
<MarkdownView
markdown={markdown}
options={{ tables: true, emoji: true }}
/>
);
};
通过MarkdownView这个组件,可以将一串markdown格式的文本转化为html。
另外我们注意到它的选项,tables为true,如果不设置这个的话,markdown中的table格式将不会被转化成表格。第二个emoji为true是支持emoji转换。
这个时候你可能要问,这只是转换了一下markdown文件而已,转换react组件呢?
我们可以看一下下面这个官方示例:
import MarkdownView from 'react-showdown';
function CustomComponent({ name }: { name: string }) {
return <span>Hello {name}!</span>;
}
const markdown = `
# 我是个标题:
<CustomComponent name="world" />`;
<MarkdownView markdown={markdown} components={{ CustomComponent }} />
在markdown文本中可以直接写上CustomComponent这个自定义的react组件代码,然后在MarkdownView的components中传入CustomComponent即可。
生成的最终html中不仅会有个标题,标题下面还会展示一个叫hello world!的文本,而不是展示<CustomComponent name="world" />这个字符串。
排疑解难
看完了上面的原理,想必您已经可以实现这样的一个文档应用了。
不过在这个过程中您可能还是会遇到一些小麻烦,这里提前给您支个招。
麻烦1:markdown转换成html后的代码高亮处理。
因为我们做的是一个组件文档,那么肯定会涉及到代码展示。
markdown文件中的代码块,使用react-showndown转换后的并没有做高亮处理。
不过react-showdown是支持Showdown的各种扩展的,其中有个扩展叫showdown-highlight,通过这个扩展可以对代码块做高亮处理。
麻烦2:react-showndown只支持简单的组件。
虽然react-showndown可以解析react组件代码,但是它也只能简单解析这个组件。如果我们演示的示例比较复杂,涉及到一些函数,还有一些库的引用,很显然不能再markdown文件中直接写。
这里我建议直接将每个组件的示例写到一个独立的js中,这个js导出一个Demo组件,然后我们在markdown文件中直接引用这个demo组件即可。
大致代码如下:
import MarkdownView from 'react-showdown';
import ButtonDemo from './ButtonDemo';
const markdown = `
# 按钮组件
组件描述
## 代码示例
<ButtonDemo />
```tsx
这里贴出以ButtonDemo组件中的代码
```
## API
| 属性 | 说明 |XXX|
|----------|----------|-----|
| title | 按钮文本 | XXX |
| type | 按钮类型 | XXX |
<ButtonDemo />`;
<MarkdownView markdown={markdown} components={{ ButtonDemo }} />
通过上面这种方式,不论我们ButtonDemo中的逻辑和功能多么复杂,展示出来都是没问题的。
麻烦3:如何将这个文档应用做到简单好用。
看了上面的代码,可能有人会觉得应该没问题了。
但是我们得明白,我们这个东西是做给业务开发的人员用的,而不是做给我们自己用的。
我业务开发人员为什么要知道你这些什么 react-showdown 的代码?
我业务开发人员还要学习你的这些鬼东西?
不是每个人都想着学这些乱七八糟的技术好吗?
我每天就只想在6点下班,就算你5分钟内给我讲明白了,你这个文档应用我用不用还两说。
你要是5分钟之内还讲不明白怎么用,那你休想我在这上面给一个公共组件写文档。
我们面对的基本就是这么一个场景,我们做这个应用是为了解决项目中实际面临的问题,是面向业务开发人员编程,而不是面向领导和KPI编程。
所以我们需要做到简单好用,将所有涉及到react-showdown这玩意的部分全部不被业务开发人员感知。
想象一下,写一个组件的文档,缩减到最少,就是一个markdown文件,和一个demo.js。
那么我们就只让业务开发人员去写这两个东西就行,把他们的工作量减少到最小。
就给他们两个文件夹,一个文件夹叫doc,里面放markdown文件,一个文件夹叫demo,里面放各个demo。
再用一个字典配置dict.js,去做个基本的配置。
如果现在有个组件叫Easy要写文档,那么我们的dict.js内容可能就是下面这样:
const dict=['Easy','Hard','XXX']
export defalt dict
只需要加个字符串Easy即可。
然后你可以在那么doc文件夹下加个markdown文件叫EasyMD.md,demo文件夹下加个文件叫EasyDemo.tsx。
之后的所有步骤全部由我们的文档应用解析dict.js后自动完成,无需用户操心。
通过这样的一种约定,我们可以将业务开发人员的工作量减到最小,把他们写组件文档的门槛降到最低。
具体代码实现就略过了,实现的关键词叫:import()函数,其他的不用多说了。
总结
虽然说这个文档应用是受前公司启发,而且因为开发时间就两天,所以比较简陋,但是至少我做到了比前公司的内部应用更简单方便,完全没有学习成本。
好了,自吹一波就得了,本篇博客到此结束。
如有疏漏之处,还请不吝赐教。
解析Markdown文件生成React组件文档的更多相关文章
- 解放生产力,自动化生成vue组件文档
一.现状 Vue框架在前端开发中应用广泛,当一个多人开发的Vue项目经过长期维护之后往往会沉淀出很多的公共组件,这个时候经常会出现一个人 开发了一个组件而其他维护者或新接手的人却不知道这个组件是做什么 ...
- vite插件-自动生成vue组件文档
特点 支持热更新 快速启动,依赖于 vite,无需另起服务 自动生成组件导航 ui 采用了vant-ui的样式 核心方法覆盖率达到了 92.86% 使用 yarn add vite-plugin-vu ...
- Markdown 文件转化为work文档
1. 电脑安装pandoc 链接:https://pan.baidu.com/s/12H5wLO0JWph5TjrbeJI6mg 密码:ssgs 下载安装包解压即可用.记得配置系统环境变量 2.命令行 ...
- 使用dumi生成react组件库文档并发布到github pages
周末两天玩了下号称西湖区东半球最牛逼的react文档站点生成工具dumi,顺带结合github pages生成了react-uni-comps文档站, 一套弄下来,感觉真香,现在还只是浅尝,高级的特性 ...
- Docz 用 MDX 写 React UI 组件文档
Docz 用 MDX 写 React UI 组件文档 前言 为了提升开发效率,创建一套 UI 组件库是一种较为有效的方式之一:可以减少重复工作.提高可复用,所以现在越来越多团队开始创建自己的 UI 组 ...
- 打造自己的Vue组件文档生成工具
程序员最讨厌的两件事情,第一种是写文档,另一种是别人没有写文档.有没有直接根据vue组件生成文档的呢?当然是有的的.但第三方使用起来不一定能和现有项目结合使用,往往需要额外的注释用来标记提取信息.使用 ...
- 使用多个项目生成Xml文件来显示帮助文档
终于到这了,我们首先将Product单独作为一个项目 WebAPI2PostMan.WebModel 并引用他,查看文档如下. 你会发现,你的注释也就是属性的描述没有了.打开App_Data/XmlD ...
- react解析markdown文件
当当当又get到了一个新技能,使用react-markdown来直接解析markdown文件(咳咳,小菜鸟的自娱自乐) 项目中遇到了一个API的那种展示方式,类似于入门手册啥的那种,如果是一个个调用接 ...
- XML解析之sax解析案例(一)读取contact.xml文件,完整输出文档内容
一.新建Demo2类: import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXPar ...
随机推荐
- MySQL5.6忘记root密码
第一步 修改 /etc/my.conf 文件 添加 skip-grant-tables 到 [mysqld] 下面就可以 这个参数的意思是设置为无需密码验证的登录 登录之后,可以添加用户,可以修改密码 ...
- 【笔记】集成学习入门之soft voting classifier和hard voting classifier
集成学习入门之soft voting classifier和hard voting classifier 集成学习 通过构建并结合多个学习器来完成学习任务,一般是先产生一组"个体学习器&qu ...
- Kurento实战之一:KMS部署和体验
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- DVWA靶场之XSS(Stored)通关
Low: <?php if( isset( $_POST[ 'btnSign' ] ) ) { // Get input $message = trim( $_POST[ 'mtxMessage ...
- SSM自学笔记(一)
本文内容 Ioc和DI Spring快速入门 Spring配置文件 Spring IoC和DI注解开发 Spring配置数据源 Spring注解开发 Spring整合Junit IoC 和 DI 1. ...
- Vmware15的安装以及Ubunt的在虚拟机上的安装
一.vmware15安装 1.百度网盘地址 链接:https://pan.baidu.com/s/1Lgez57n50QEW97HNdYZCfQ 提取码:9wvy 2.下载到本地后 3.双击安装程序 ...
- [SWMM]软件启动不了,出现 “ RPC服务器不可用 ” 错误
[问题]打开SWMM5.1软件时,初选"RPC服务器不可用"的错误 [解决]计算机管理--服务 设置Print Spooler服务状态为启动,并设置为自启动.
- ProjectEuler 007题
题目:By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is ...
- easyexcel
导出: package com.example.demo.excel.demo0; import com.alibaba.excel.annotation.ExcelProperty; import ...
- C# .NetCore简单实现无限递归的功能
1:在实际开发中,我们会经常使用到无限递归的情况,如菜单,父子级等的情况 2:Code 1 using System; 2 using System.Collections.Generic; 3 us ...