@alifd/api-extractor
一个从 React 组件代码中提取 API 信息的工具,一般用来生成 API 文档,开发编辑器组件 API 提示插件以及开发页面搭建平台组件物料的属性面板,代码中附加信息书写方式来源于jsDoc,整体底层解析工具依赖于 react-docgen 和 doctrine。
Feature
- 支持通过
propTypes
获得属性类型 - 支持通过
defaultProps
获得属性默认值 - 支持通过
propTypes
上的 jsDoc 注释获得属性描述,自定义属性默认值 - 支持通过书写 jsDoc 获取函数类型属性的参数和返回值
- 支持通过书写 jsDoc 获取对象类型属性的属性
- 支持通过书写 jsDoc 获取组件静态方法和实例方法的描述,参数以及返回值
- 支持根据提取的 API 信息生成 markdown 片段,方便灵活组织API文档
- 支持通过按照约定书写组件上的 jsDoc 来获得父组件与子组件关系
- 支持通过
propTypes = {...Base.propTypes}
的方式扩展
Install
npm install @alifd/api-extractor
Usage
const extractor = require('@alifd/api-extractor');
const apiInfo = extractor.extract(componentDirPath);
// const apiInfo = extractor.extractFile(componentFilePath);
API
extract(componentDirPath, options, parentMap)
参数:
- componentDirPath
String
组件代码文件夹路径 - options
Object
可选项- md
Boolean
是否生成props
和method
的 markdown 片段,默认值为false
- fileErrorHandler
Function
自定义单个文件的错误处理函数,默认直接抛出错误
- md
- parentMap
Object
可选项 组件继承关系,例如 Nav 继承自 Menu ,通过该参数可将 Menu 上的props merge到 Nav上
{
'Nav': {
name: 'Menu',
path: 'my-path/src/menu'
},
'Nav.Item': {
name: 'Menu.Item',
path: 'my-path/src/menu'
}
}
返回值:
Object
参考下方 Example
extractFile(componentFilePath, options)
参数:
- componentFilePath
String
组件代码文件路径 - options
Object
可选项- md
Boolean
是否生成props
和method
的 markdown 片段,默认值为false
- md
返回值:
Object
参考下方 Example
generatePropsMD(props)
参数:
- props
Object
使用extract
方法生成api信息的props
属性
返回值:
String
props对应的markdown文本
generateMethodMD(method)
参数:
- method
Object
使用extract
方法生成api信息的methods
属性的Item
返回值:
String
method对应的markdown文本
Example
如果传入的组件代码根路径下存在以下两个文件:
menu.js
import React, { Component} from 'react';
import PropTypes from 'prop-types';
/**
* Menu
**/
export default class Menu extends Component {
static propTypes = {
/**
* the menu size
**/
size: PropTypes.string,
/**
* select menu callback
* @param {Array} selectedKeys the seleced keys
**/
onSelect: PropTypes.func
};
static defaultProps = {
size: 'medium',
onSelect: () => {}
};
render() {
// ...
}
}
menu-item.js
import React, { Component} from 'react';
import PropTypes from 'prop-types';
/**
* Menu.Item
**/
export default class Item extends Component {
// ...
}
我们会得到如下的 json 结构:
{
"name": "Menu", // 组件名
"props": {
"size": { // 属性名
"type": {
"name": "string" // 属性类型
},
"required": false, // 属性是否必需
"description": "the menu size", // 属性描述
"defaultValue": {
"value": "'medium'", // 属性默认值
"computed": false
}
},
"onSelect": {
"type": {
"name": "func"
},
"required": false,
"description": "select menu callback",
"defaultValue": {
"value": "() => {}",
"computed": false
},
"docblock": "select menu callback\n@param {Array} selectedKeys the seleced keys",
"params": [ // 函数参数
{
"name": "selectedKeys", // 函数参数名
"description": "the seleced keys", // 函数参数描述
"type": {
"name": "Array" // 函数参数类型
}
}
],
"returns": null // 函数返回值
}
},
"propsMD": "...", // 开启了md参数后,所有属性渲染出的 Markdown 文件
"methods": [], // 方法
"subComponents": [ // 子组件
{
"description": "Item",
// ...
}
]
}
该 json 结构在react-docgen 生成的 json 结构基础上扩展而成。主要增加了subComponents
,propsMD
,属性为函数时的parmas
,return
和属性为对象时的properties
结构。
propsMD
属性一般用来生成README.md中的API文档,Menu
组件的 propsMD
具体如下所示:
参数 | 说明 | 类型 | 默认值
-----|-----|-----|-----
size | the menu size | String | 'medium'
onSelect | select menu callback<br><br>**签名**:<br>Function(selectedKeys: Array) => void<br>**参数**:<br>selectedKeys {Array} the seleced keys | Function | () => {}
Note
-
只有添加了 jsDoc 注释的组件类,组件的属性以及组件的方法,才会被工具提取出相应的 API 信息。
-
只有在文件中被
export default
的组件类才会被提取 API 信息 -
默认传入的组件路径下只有一个根组件,如果想对外暴露两个组件,如
Row
和Col
,也请在 jsDoc 的注释中添加根组件的前缀,如Grid.Row
和Grid.Col
。 -
如果想控制子组件在
subComponents
中出现的顺序,以方便生成对应的 API 文档,可以为组件类的 jsDoc 注释中添加order
字段(默认按照首字母顺序排列),如下所示:row.js
/** * Grid.Row * @order 1 */ export default class Row extends Component { // ... }
col.js
/** * Grid.Col * @order 2 */ export default class Col extends Component { // ... }
-
工具只支持一层的子组件,也就是说无法处理
AAA.BBB.CCC
的情况,当然我们也不认为这是一个组件应该对外暴露的使用方式。 -
如果想自定义属性默认值,可以采用下面方法(其优先级高于
defaultProps
):/** * Description of prop "aaa" * @default custom **/ aaa: PropTypes.string,
-
如果像添加属性枚举值的描述,可以采用下面方法
/** * Description of prop "aaa" * @enumdesc left, right **/ bbb: PropTypes.oneOf(['left', 'right']),
-
可以通过书写 description tag 来为组件增加描述
/** * Upload.ImageUpload * @description 继承 [Upload](http://fusion-demo.alibaba-inc.com/api/1.0/views/next?themeId=next&name=upload#upload-1) 的 API,除非特别说明 */ class ImageUpload extends Component { //... }
-
以下的写法,可以获得 Base 组件中声明的 API 信息
import Base from './base'; export default class Menu extends Component { static propTypes = { ...Base.propTypes, /** * description */ onSelect: PropTypes.func } }