Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"generate:themes-dev": "node scripts/generate-themes-dev.js",
"generate:file:taro": "node scripts/taro/generate-nutui-taro.js",
"generate:file:taro:pages": "node scripts/taro/generate-taro-pages.js",
"generate:props_json": "PROPS_JSON=true node scripts/build-comments-to-dts.mjs",
"lint": "eslint ./src/packages/*/",
"lint:fix": "eslint --fix ./src/packages",
"prepare": "husky && npm run generate:file && npm run generate:file:taro && npm run generate:file:taro:pages",
Expand Down
132 changes: 58 additions & 74 deletions scripts/build-comments-to-dts.mjs
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
/**
* 向生成的组件类型文件中注入注释
* 通过在其他脚本 import codeShift 方法,可以向生成的组件类型文件中增加 JSDoc
* 通过npm scripts 触发,可在 src/types 下生成 props.json 文件
*/
import * as path from 'path'
import { dirname } from 'path'
import fse from 'fs-extra'
import j from 'jscodeshift'
import markdownit from 'markdown-it'
import { fileURLToPath } from 'url'
import { dirname } from 'path'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const dist = 'release/h5/dist'

const PROPS_JSON = process.env.PROPS_JSON

/**
* 通过 cofnig.json 获取所有组件的数据
*/
function readAllComponents() {
const config = JSON.parse(fse.readFileSync(path.join(__dirname, '../src/config.json')).toString())
const components = config.nav.reduce(function (accumulator, currentValue) {
const components = config.nav.reduce(function(accumulator, currentValue) {
currentValue.packages.forEach((pkg) => {
if (pkg.exclude || pkg.version !== '2.0.0') {
if (pkg.exclude) {
return
}
accumulator.push(pkg)
Expand Down Expand Up @@ -52,7 +54,7 @@ function extractPropsTable(doc) {
token.type == 'heading_open' &&
token.tag == 'h3' &&
sources[index + 1].type == 'inline' &&
sources[index + 1].content === 'Props'
sources[index + 1].content.toLowerCase() == 'props'
) {
const componentName = sources[index - 2].content
let startIndex = index + 3
Expand Down Expand Up @@ -99,95 +101,77 @@ function markdownTable2Json(table) {
return rows
}

function addComments(dtsPath, propsTable, componentName) {
const source = fse.readFileSync(dtsPath).toString()

function findInTable(identifierName) {
const [info] = propsTable.filter(
(t) => t[0].replace(/'/g, '') === identifierName
)
return info
}

const transform = (file, api) => {
const j = api.jscodeshift.withParser('ts')
return j(file.source)
.find(j.TSInterfaceDeclaration, {
id: {
name: componentName + 'Props',
type: 'Identifier',
},
})
.forEach((path) => {
path.value?.body?.body?.forEach((item) => {
if (!item.key) return
const info = findInTable(item.key.name)
if (!info) return
item['comments'] = [
j.commentBlock(`*\n* ${info[1]}\n* @default ${info[3]}\n`),
]
})
})
.toSource()
}
const result = transform({ source }, { jscodeshift: j })
if (result) {
fse.writeFileSync(dtsPath, result)
}
}

function getDtsPath(key, outDir) {
// Tabs.Tabpane -> tabpane
let name
if (key === 'Tabs.Tabpane') {
name = 'tabpane'
} else {
name = key.toLowerCase().replace('.', '')
}
const file = path.join(__dirname, `../${outDir}/es/packages`, name, name + '.d.ts')
return file
}

function getComponentName(key) {
// Tabs.Tabpane -> tabpane
let name = key
if (key === 'Tabs.Tabpane') {
name = 'TabPane'
}
return name.replace('.', '')
}

/**
* step 1: 从 config.json 中读取组件列表,迭代
* step a: 读取组件的 doc.md 或 doc.taro.md
* step b: 提取文档中的 Props 相关的表格,并转换为 JSON 数据
* step c: 添加注释
*/
export function codeShift(env) {
export function codeShift(platform) {
const components = readAllComponents()
const componentsProps = {}
components.forEach((component) => {
const { name } = component
const componentDocumentPath = path.join(
__dirname,
'../src/packages',
name.toLowerCase(),
env === 'taro' ? 'doc.taro.md' : 'doc.md'
platform === 'taro' ? 'doc.taro.md' : 'doc.md',
)
if (fse.pathExistsSync(componentDocumentPath)) {
const tables = extractPropsTable(
readComponentDocument(componentDocumentPath)
readComponentDocument(componentDocumentPath),
)
Object.keys(tables).forEach((key) => {
const dtsPath = getDtsPath(key, env !== 'taro' ? dist : dist.replace('h5', env))
if (fse.pathExistsSync(dtsPath)) {
const table = markdownTable2Json(tables[key])
addComments(dtsPath, table, getComponentName(key))
} else {
console.warn(name + ' dts file does not exist')
}
const table = markdownTable2Json(tables[key])
componentsProps[key.toLowerCase()] = table.reduce((acc, [key, desc, types, defaultValue]) => {
acc[key] = {
desc: desc,
types: types,
defaultValue: defaultValue,
}
return acc
}, {})
})
} else {
// console.warn(name + ' document file does not exist')
}
if (!PROPS_JSON) {
if (!component.exportEmpty) addJSDoc(componentsProps, name, platform)
}
})
if (PROPS_JSON) {
const jsonContent = JSON.stringify(componentsProps, ' ', 2)
fse.writeFileSync(path.join(__dirname, '../src/types', `props.json`), jsonContent)
}
}

function addJSDoc(propsJson, componentName, platform) {
const transform = (file, api) => {
const j = api.jscodeshift.withParser('ts')
return j(file.source)
.find(j.TSInterfaceDeclaration, {
id: {
name: `Base${componentName}`,
type: 'Identifier',
},
})
.forEach((path) => {
path.value?.body?.body?.forEach((item) => {
if (!item.key) return
const info = propsJson[componentName.toLowerCase()][item.key.name]
if (!info) return
item['comments'] = [
j.commentBlock(`*\n* ${info['desc']}\n`),
]
})
})
.toSource()
}
const baseType = path.join(__dirname, `../release/${platform || 'h5'}/dist/es/types/spec/${componentName.toLowerCase()}/base.d.ts`)
const source = fse.readFileSync(baseType, { encoding: 'utf8' })
const result = transform({ source }, { jscodeshift: j })
fse.writeFileSync(baseType, result)
}

PROPS_JSON && codeShift('h5')
1 change: 0 additions & 1 deletion scripts/build-taro.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ const transform = (file, api, replace) => {
return
}
const dir = join(__dirname, alias.replace('@/', '../src/'))
console.log(alias, file)
if (file.path) {
path.node.source.value = relativePath(dir, file.path)?.replace(
'.taro',
Expand Down
1 change: 1 addition & 0 deletions src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@
"show": false,
"taro": true,
"author": "Alex.hxy",
"exportEmpty": true,
"dd": true
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/packages/datepickerview/doc.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { DatePickerView } from '@nutui/nutui'

:::

## DatePicker
## DatePickerView

### Props

Expand Down
2 changes: 1 addition & 1 deletion src/packages/datepickerview/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { DatePickerView } from '@nutui/nutui'

:::

## DatePicker
## DatePickerView

### Props

Expand Down
2 changes: 1 addition & 1 deletion src/packages/datepickerview/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { DatePickerView } from '@nutui/nutui-taro'

:::

## DatePicker
## DatePickerView

### Props

Expand Down
2 changes: 1 addition & 1 deletion src/packages/datepickerview/doc.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { DatePickerView } from '@nutui/nutui'

:::

## DatePicker
## DatePickerView

### Props

Expand Down
2 changes: 1 addition & 1 deletion src/packages/rate/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ import { Rate } from '@nutui/nutui-react-taro'

## Rate

## Props
### Props

| 属性 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
Expand Down
10 changes: 7 additions & 3 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ export * from './spec/picker/base'
export * from './spec/picker/h5'
export * from './spec/picker/taro'

export * from './spec/pickerview/base'
export * from './spec/pickerview/h5'
export * from './spec/pickerview/taro'

export * from './spec/noticebar/base'
export * from './spec/noticebar/h5'
export * from './spec/noticebar/taro'
Expand Down Expand Up @@ -344,6 +348,6 @@ export * from './spec/audio/base'
export * from './spec/audio/h5'
export * from './spec/audio/taro'

export * from './spec/step/base'
export * from './spec/step/h5'
export * from './spec/step/taro'
export * from '@/types/spec/steps/base'
export * from '@/types/spec/steps/h5'
export * from '@/types/spec/steps/taro'
11 changes: 0 additions & 11 deletions src/types/spec/picker/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,3 @@ export interface BasePicker<POPUP_PROPS = any> extends BaseProps {
onChange?: (args0: PickerOnChangeCallbackParameter) => void
children?: any
}

export interface BasePickerView extends BaseProps {
setRefs?: (ref: any) => any
options: PickerOptions[]
value?: PickerValue[]
defaultValue?: PickerValue[]
threeDimensional?: boolean
duration?: number | string
renderLabel: (item: PickerOption) => React.ReactNode
onChange?: (arg0: PickerOnChangeCallbackParameter) => void
}
4 changes: 2 additions & 2 deletions src/types/spec/picker/h5.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BasePicker, BasePickerView, BasePickerRoller } from './base'
import { BasePicker, BasePickerRoller } from './base'
import { WebPopupProps } from '../popup/h5'

export interface WebPickerProps extends BasePicker<WebPopupProps> {}
export interface WebPickerViewProps extends BasePickerView {}

export interface WebPickerRollerProps extends BasePickerRoller {}
3 changes: 1 addition & 2 deletions src/types/spec/picker/taro.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { BasePicker, BasePickerRoller, BasePickerView } from './base'
import { BasePicker, BasePickerRoller } from './base'
import { TaroPopupProps } from '../popup/taro'

export interface TaroPickerProps extends BasePicker<TaroPopupProps> {}
export interface TaroPickerViewProps extends BasePickerView {}
export interface TaroPickerRollerProps extends BasePickerRoller {}
18 changes: 18 additions & 0 deletions src/types/spec/pickerview/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { BaseProps } from '../../base/props'
import {
PickerOnChangeCallbackParameter,
PickerOption,
PickerOptions,
PickerValue,
} from '../picker/base'

export interface BasePickerView extends BaseProps {
setRefs?: (ref: any) => any
options: PickerOptions[]
value?: PickerValue[]
defaultValue?: PickerValue[]
threeDimensional?: boolean
duration?: number | string
renderLabel: (item: PickerOption) => React.ReactNode
onChange?: (arg0: PickerOnChangeCallbackParameter) => void
}
3 changes: 3 additions & 0 deletions src/types/spec/pickerview/h5.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { BasePickerView } from './base'

export interface WebPickerViewProps extends BasePickerView {}
3 changes: 3 additions & 0 deletions src/types/spec/pickerview/taro.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { BasePickerView } from './base'

export interface TaroPickerViewProps extends BasePickerView {}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading