Skip to content

Commit a73cf6b

Browse files
authored
chore: 类型文件中增加 jsdoc (#3073)
* fix: run error * chore: 支持 npm scripts 调用,支持作为模块调用 * chore: 构建脚本支持触发生成 JSDoc 的逻辑 * chore: steps * chore: steps * feat: 处理 TypeAliasDeclaration 节点 * feat: 删除调试逻辑 * fix: 类型导出的路径去掉别名 * fix: 有些 alias 没有成员,排除这个异常情况
1 parent e535162 commit a73cf6b

File tree

19 files changed

+113
-98
lines changed

19 files changed

+113
-98
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
"generate:themes-dev": "node scripts/generate-themes-dev.js",
8383
"generate:file:taro": "node scripts/taro/generate-nutui-taro.js",
8484
"generate:file:taro:pages": "node scripts/taro/generate-taro-pages.js",
85+
"generate:props_json": "PROPS_JSON=true node scripts/build-comments-to-dts.mjs",
8586
"lint": "eslint ./src/packages/*/",
8687
"lint:fix": "eslint --fix ./src/packages",
8788
"prepare": "husky && npm run generate:file && npm run generate:file:taro && npm run generate:file:taro:pages",

scripts/build-comments-to-dts.mjs

Lines changed: 72 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
11
/**
2-
* 向生成的组件类型文件中注入注释
2+
* 通过在其他脚本 import codeShift 方法,可以向生成的组件类型文件中增加 JSDoc
3+
* 通过npm scripts 触发,可在 src/types 下生成 props.json 文件
34
*/
45
import * as path from 'path'
6+
import { dirname } from 'path'
57
import fse from 'fs-extra'
68
import j from 'jscodeshift'
79
import markdownit from 'markdown-it'
810
import { fileURLToPath } from 'url'
9-
import { dirname } from 'path'
1011

1112
const __filename = fileURLToPath(import.meta.url)
1213
const __dirname = dirname(__filename)
13-
const dist = 'release/h5/dist'
14+
15+
const PROPS_JSON = process.env.PROPS_JSON
1416

1517
/**
1618
* 通过 cofnig.json 获取所有组件的数据
1719
*/
1820
function readAllComponents() {
1921
const config = JSON.parse(fse.readFileSync(path.join(__dirname, '../src/config.json')).toString())
20-
const components = config.nav.reduce(function (accumulator, currentValue) {
22+
const components = config.nav.reduce(function(accumulator, currentValue) {
2123
currentValue.packages.forEach((pkg) => {
22-
if (pkg.exclude || pkg.version !== '2.0.0') {
24+
if (pkg.exclude) {
2325
return
2426
}
2527
accumulator.push(pkg)
@@ -52,7 +54,7 @@ function extractPropsTable(doc) {
5254
token.type == 'heading_open' &&
5355
token.tag == 'h3' &&
5456
sources[index + 1].type == 'inline' &&
55-
sources[index + 1].content === 'Props'
57+
sources[index + 1].content.toLowerCase() == 'props'
5658
) {
5759
const componentName = sources[index - 2].content
5860
let startIndex = index + 3
@@ -99,95 +101,91 @@ function markdownTable2Json(table) {
99101
return rows
100102
}
101103

102-
function addComments(dtsPath, propsTable, componentName) {
103-
const source = fse.readFileSync(dtsPath).toString()
104-
105-
function findInTable(identifierName) {
106-
const [info] = propsTable.filter(
107-
(t) => t[0].replace(/'/g, '') === identifierName
108-
)
109-
return info
110-
}
111-
112-
const transform = (file, api) => {
113-
const j = api.jscodeshift.withParser('ts')
114-
return j(file.source)
115-
.find(j.TSInterfaceDeclaration, {
116-
id: {
117-
name: componentName + 'Props',
118-
type: 'Identifier',
119-
},
120-
})
121-
.forEach((path) => {
122-
path.value?.body?.body?.forEach((item) => {
123-
if (!item.key) return
124-
const info = findInTable(item.key.name)
125-
if (!info) return
126-
item['comments'] = [
127-
j.commentBlock(`*\n* ${info[1]}\n* @default ${info[3]}\n`),
128-
]
129-
})
130-
})
131-
.toSource()
132-
}
133-
const result = transform({ source }, { jscodeshift: j })
134-
if (result) {
135-
fse.writeFileSync(dtsPath, result)
136-
}
137-
}
138-
139-
function getDtsPath(key, outDir) {
140-
// Tabs.Tabpane -> tabpane
141-
let name
142-
if (key === 'Tabs.Tabpane') {
143-
name = 'tabpane'
144-
} else {
145-
name = key.toLowerCase().replace('.', '')
146-
}
147-
const file = path.join(__dirname, `../${outDir}/es/packages`, name, name + '.d.ts')
148-
return file
149-
}
150-
151-
function getComponentName(key) {
152-
// Tabs.Tabpane -> tabpane
153-
let name = key
154-
if (key === 'Tabs.Tabpane') {
155-
name = 'TabPane'
156-
}
157-
return name.replace('.', '')
158-
}
159-
160104
/**
161105
* step 1: 从 config.json 中读取组件列表,迭代
162106
* step a: 读取组件的 doc.md 或 doc.taro.md
163107
* step b: 提取文档中的 Props 相关的表格,并转换为 JSON 数据
164108
* step c: 添加注释
165109
*/
166-
export function codeShift(env) {
110+
export function codeShift(platform) {
167111
const components = readAllComponents()
112+
const componentsProps = {}
168113
components.forEach((component) => {
169114
const { name } = component
170115
const componentDocumentPath = path.join(
171116
__dirname,
172117
'../src/packages',
173118
name.toLowerCase(),
174-
env === 'taro' ? 'doc.taro.md' : 'doc.md'
119+
platform === 'taro' ? 'doc.taro.md' : 'doc.md',
175120
)
176121
if (fse.pathExistsSync(componentDocumentPath)) {
177122
const tables = extractPropsTable(
178-
readComponentDocument(componentDocumentPath)
123+
readComponentDocument(componentDocumentPath),
179124
)
180125
Object.keys(tables).forEach((key) => {
181-
const dtsPath = getDtsPath(key, env !== 'taro' ? dist : dist.replace('h5', env))
182-
if (fse.pathExistsSync(dtsPath)) {
183-
const table = markdownTable2Json(tables[key])
184-
addComments(dtsPath, table, getComponentName(key))
185-
} else {
186-
console.warn(name + ' dts file does not exist')
187-
}
126+
const table = markdownTable2Json(tables[key])
127+
componentsProps[key.toLowerCase()] = table.reduce((acc, [key, desc, types, defaultValue]) => {
128+
acc[key] = {
129+
desc: desc,
130+
types: types,
131+
defaultValue: defaultValue,
132+
}
133+
return acc
134+
}, {})
188135
})
189136
} else {
190137
// console.warn(name + ' document file does not exist')
191138
}
139+
if (!PROPS_JSON) {
140+
if (!component.exportEmpty) addJSDoc(componentsProps, name, platform)
141+
}
192142
})
143+
if (PROPS_JSON) {
144+
const jsonContent = JSON.stringify(componentsProps, ' ', 2)
145+
fse.writeFileSync(path.join(__dirname, '../src/types', `props.json`), jsonContent)
146+
}
193147
}
148+
149+
function addJSDoc(propsJson, componentName, platform) {
150+
const transform = (file, api) => {
151+
const j = api.jscodeshift.withParser('ts')
152+
const ast = j(file.source)
153+
function addComment(item) {
154+
if (!item.key) return
155+
const description = propsJson[componentName.toLowerCase()][item.key.name]
156+
if (!description) return
157+
item['comments'] = [
158+
j.commentBlock(`*\n* ${description['desc']}\n`),
159+
]
160+
}
161+
ast
162+
.find(j.TSTypeAliasDeclaration).forEach((path) => {
163+
const annotationTypes = path.value.typeAnnotation.types
164+
if (!annotationTypes) return
165+
const typeLiteral = annotationTypes[annotationTypes.length - 1]
166+
if (!typeLiteral.members) return
167+
typeLiteral.members.forEach((item) => {
168+
addComment(item)
169+
})
170+
})
171+
ast.find(j.TSInterfaceDeclaration, {
172+
id: {
173+
name: `Base${componentName}`,
174+
type: 'Identifier',
175+
},
176+
})
177+
.forEach((path) => {
178+
path.value?.body?.body?.forEach((item) => {
179+
addComment(item)
180+
})
181+
})
182+
183+
return ast.toSource()
184+
}
185+
const baseType = path.join(__dirname, `../release/${platform || 'h5'}/dist/es/types/spec/${componentName.toLowerCase()}/base.d.ts`)
186+
const source = fse.readFileSync(baseType, { encoding: 'utf8' })
187+
const result = transform({ source }, { jscodeshift: j })
188+
fse.writeFileSync(baseType, result)
189+
}
190+
191+
PROPS_JSON && codeShift('h5')

scripts/build-taro.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ const transform = (file, api, replace) => {
5959
return
6060
}
6161
const dir = join(__dirname, alias.replace('@/', '../src/'))
62-
console.log(alias, file)
6362
if (file.path) {
6463
path.node.source.value = relativePath(dir, file.path)?.replace(
6564
'.taro',

src/config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@
394394
"show": false,
395395
"taro": true,
396396
"author": "Alex.hxy",
397+
"exportEmpty": true,
397398
"dd": true
398399
},
399400
{

src/packages/datepickerview/doc.en-US.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { DatePickerView } from '@nutui/nutui'
2424

2525
:::
2626

27-
## DatePicker
27+
## DatePickerView
2828

2929
### Props
3030

src/packages/datepickerview/doc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { DatePickerView } from '@nutui/nutui'
2828

2929
:::
3030

31-
## DatePicker
31+
## DatePickerView
3232

3333
### Props
3434

src/packages/datepickerview/doc.taro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { DatePickerView } from '@nutui/nutui-taro'
2828

2929
:::
3030

31-
## DatePicker
31+
## DatePickerView
3232

3333
### Props
3434

src/packages/datepickerview/doc.zh-TW.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { DatePickerView } from '@nutui/nutui'
2828

2929
:::
3030

31-
## DatePicker
31+
## DatePickerView
3232

3333
### Props
3434

src/packages/rate/doc.taro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ import { Rate } from '@nutui/nutui-react-taro'
108108

109109
## Rate
110110

111-
## Props
111+
### Props
112112

113113
| 属性 | 说明 | 类型 | 默认值 |
114114
| --- | --- | --- | --- |

src/types/index.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ export * from './spec/picker/base'
158158
export * from './spec/picker/h5'
159159
export * from './spec/picker/taro'
160160

161+
export * from './spec/pickerview/base'
162+
export * from './spec/pickerview/h5'
163+
export * from './spec/pickerview/taro'
164+
161165
export * from './spec/noticebar/base'
162166
export * from './spec/noticebar/h5'
163167
export * from './spec/noticebar/taro'
@@ -344,6 +348,6 @@ export * from './spec/audio/base'
344348
export * from './spec/audio/h5'
345349
export * from './spec/audio/taro'
346350

347-
export * from './spec/step/base'
348-
export * from './spec/step/h5'
349-
export * from './spec/step/taro'
351+
export * from './spec/steps/base'
352+
export * from './spec/steps/h5'
353+
export * from './spec/steps/taro'

0 commit comments

Comments
 (0)