feat: add docs gen script for omi-cli component template
This commit is contained in:
parent
c0b7affb03
commit
8f1672c4e7
|
@ -0,0 +1,31 @@
|
|||
# Counter
|
||||
|
||||
> Counter
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm i
|
||||
```
|
||||
|
||||
## Dev
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
## Preview
|
||||
|
||||
```bash
|
||||
//html mode demo
|
||||
http://localhost:3000
|
||||
|
||||
//jsx mode demo
|
||||
http://localhost:3000/demo.html
|
||||
```
|
||||
|
||||
## Release
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
|
@ -1,31 +1,46 @@
|
|||
# Counter
|
||||
# Counter_to_be_replace
|
||||
|
||||
> Counter
|
||||
Description for component.
|
||||
|
||||
## Install
|
||||
- [→ CodePen](https://codepen.io/omijs/pen/)
|
||||
|
||||
```bash
|
||||
npm i
|
||||
## Import
|
||||
|
||||
```js
|
||||
import '@omiu/counter_to_be_replace'
|
||||
```
|
||||
|
||||
## Dev
|
||||
Or use script tag to ref it.
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```html
|
||||
<script src="https://unpkg.com/@omiu/counter_to_be_replace"></script>
|
||||
```
|
||||
|
||||
## Preview
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
//html mode demo
|
||||
http://localhost:3000
|
||||
|
||||
//jsx mode demo
|
||||
http://localhost:3000/demo.html
|
||||
```html
|
||||
<o-counter_to_be_replace></o-counter_to_be_replace>
|
||||
```
|
||||
|
||||
## Release
|
||||
## API
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
### Props
|
||||
|
||||
```tsx
|
||||
{
|
||||
count?: number
|
||||
onCountChanged?: (evt: CustomEvent) => void
|
||||
}
|
||||
```
|
||||
|
||||
### Default Props
|
||||
|
||||
```tsx
|
||||
{
|
||||
count: 1
|
||||
}
|
||||
```
|
||||
|
||||
### Events
|
||||
|
||||
- CountChanged
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# Counter_to_be_replace 计数器
|
||||
|
||||
计数器描述,待替换。
|
||||
|
||||
<iframe height="351" style="width: 100%;" scrolling="no" title="OMIU Counter_to_be_replace" src="https://codepen.io/omijs/embed/?height=351&theme-id=default&default-tab=html,result" frameborder="no" allowtransparency="true" allowfullscreen="true" loading="lazy">
|
||||
See the Pen <a href='https://codepen.io/omijs/pen/'>OMIU Checkbox</a> by OMI
|
||||
(<a href='https://codepen.io/omijs'>@omijs</a>) on <a href='https://codepen.io'>CodePen</a>.
|
||||
</iframe>
|
||||
|
||||
## 导入
|
||||
|
||||
```js
|
||||
import '@omiu/counter_to_be_replace'
|
||||
```
|
||||
|
||||
或者直接 script 标签引入。
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/@omiu/counter_to_be_replace"></script>
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
```html
|
||||
<o-counter_to_be_replace></o-counter_to_be_replace>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### 属性
|
||||
|
||||
```tsx
|
||||
{
|
||||
count?: number
|
||||
onCountChanged?: (evt: CustomEvent) => void
|
||||
}
|
||||
```
|
||||
|
||||
### 默认属性
|
||||
|
||||
```tsx
|
||||
{
|
||||
count: 1
|
||||
}
|
||||
```
|
||||
|
||||
### Events
|
||||
|
||||
- CountChanged
|
|
@ -1,20 +1,31 @@
|
|||
{
|
||||
"name": "@omiu/counter_to_be_replace",
|
||||
"description": "Description for component.",
|
||||
"version": "0.0.0",
|
||||
"docsExtend": {
|
||||
"cnName": "计数器",
|
||||
"cnDescription": "计数器描述,待替换。",
|
||||
"codepen": "",
|
||||
"codepenHeight": 351,
|
||||
"codepenDefaultTab": "html,result"
|
||||
},
|
||||
"main": "dist/index.es.js",
|
||||
"exports": {
|
||||
".": "./dist/index.es.js"
|
||||
},
|
||||
"types": "types/index.d.ts",
|
||||
"scripts": {
|
||||
"start": "yarn watch & vite",
|
||||
"dev": "yarn start",
|
||||
"build": "vite build && yarn build:scss",
|
||||
"start": "npm run watch & vite",
|
||||
"clean": "rm -rf dist",
|
||||
"dev": "npm run start",
|
||||
"build": "vite build && npm run build:scss",
|
||||
"build:demo": "vite build",
|
||||
"build:scss": "sass src/index.scss src/index.css",
|
||||
"docs": "esno ./scripts/docs-gen.ts",
|
||||
"watch": "sass --watch src/index.scss src/index.css --no-source-map",
|
||||
"pretest": "yarn build",
|
||||
"test": "web-test-runner \"test/*.js\" --node-resolve"
|
||||
"pretest": "npm run build",
|
||||
"test": "web-test-runner \"test/*.js\" --node-resolve",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"files_to_be_replace": [
|
||||
"dist",
|
||||
|
@ -26,11 +37,12 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@open-wc/testing": "^2.5.33",
|
||||
"@types/node": "^16.7.13",
|
||||
"@types/node": "^16.9.1",
|
||||
"@web/test-runner": "^0.13.17",
|
||||
"sass": "^1.39.0",
|
||||
"typescript": "^4.4.2",
|
||||
"vite": "^2.5.4"
|
||||
"esno": "^0.9.1",
|
||||
"sass": "^1.41.0",
|
||||
"typescript": "^4.4.3",
|
||||
"vite": "^2.5.7"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
// 自动扫描 index.tsx 生成 README
|
||||
import fs from 'fs'
|
||||
// package 是严格模式下的保留字,使用 pkg 替代
|
||||
import pkg from '../package.json'
|
||||
import { pascalCase, extract } from './utils'
|
||||
import { generateAPIDocs, generateImportAndUsageDocs } from './docs'
|
||||
|
||||
const srcFile = './src/index.tsx'
|
||||
const content = fs.readFileSync(srcFile, 'utf-8')
|
||||
|
||||
const propsStartWith = 'export type Attrs = {'
|
||||
const props = extract(propsStartWith, content).replace(
|
||||
propsStartWith.slice(0, -1),
|
||||
''
|
||||
)
|
||||
|
||||
const defaultPropsStartWith = 'static defaultProps = {'
|
||||
const defaultProps = extract('static defaultProps = {', content)
|
||||
.replace(defaultPropsStartWith.slice(0, -1), '')
|
||||
.replace(/ }/g, '}')
|
||||
.replace(/ /g, ' ')
|
||||
|
||||
const eventContexts = content.match(
|
||||
new RegExp('this.fire\\([\\s\\S]*?[,|)]', 'g')
|
||||
)
|
||||
|
||||
const pkgName = pkg.name
|
||||
const name = pkgName.split('/')[1]
|
||||
|
||||
const upperCaseName = pascalCase(name)
|
||||
const tagName = 'o-' + name
|
||||
|
||||
// fire 附近打标标记 event.detail 类型?
|
||||
let events: string[]
|
||||
let eventMap:
|
||||
| {
|
||||
[key: string]: any
|
||||
}
|
||||
| undefined = undefined
|
||||
|
||||
if (eventContexts) {
|
||||
events = eventContexts.map((event) => {
|
||||
return event.replace("this.fire('", '').replace("',", '').replace("')", '')
|
||||
})
|
||||
eventMap = {}
|
||||
events.forEach((event) => {
|
||||
if (eventMap) {
|
||||
eventMap[event] = 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const cnContent = `# ${upperCaseName} ${pkg.docsExtend.cnName}
|
||||
|
||||
${pkg.docsExtend.cnDescription}
|
||||
|
||||
<iframe height="${
|
||||
pkg.docsExtend.codepenHeight
|
||||
}" style="width: 100%;" scrolling="no" title="OMIU ${upperCaseName}" src="https://codepen.io/omijs/embed/${
|
||||
pkg.docsExtend.codepen
|
||||
}?height=${pkg.docsExtend.codepenHeight}&theme-id=default&default-tab=${
|
||||
pkg.docsExtend.codepenDefaultTab
|
||||
}" frameborder="no" allowtransparency="true" allowfullscreen="true" loading="lazy">
|
||||
See the Pen <a href='https://codepen.io/omijs/pen/${
|
||||
pkg.docsExtend.codepen
|
||||
}'>OMIU Checkbox</a> by OMI
|
||||
(<a href='https://codepen.io/omijs'>@omijs</a>) on <a href='https://codepen.io'>CodePen</a>.
|
||||
</iframe>
|
||||
|
||||
${generateImportAndUsageDocs('zh', {
|
||||
pkgName,
|
||||
tagName
|
||||
})}
|
||||
${generateAPIDocs('zh', {
|
||||
props,
|
||||
defaultProps,
|
||||
eventMap
|
||||
})}
|
||||
`
|
||||
|
||||
// todo: write to docs
|
||||
// fs.writeFileSync(`../docs-src/src/docs/zh-cn/${name}.md`, cnContent)
|
||||
fs.writeFileSync('./README.zh.md', cnContent)
|
||||
|
||||
const enContent = `# ${upperCaseName}
|
||||
|
||||
${pkg.description}
|
||||
|
||||
<iframe height="${
|
||||
pkg.docsExtend.codepenHeight
|
||||
}" style="width: 100%;" scrolling="no" title="OMIU ${upperCaseName}" src="https://codepen.io/omijs/embed/${
|
||||
pkg.docsExtend.codepen
|
||||
}?height=${pkg.docsExtend.codepenHeight}&theme-id=default&default-tab=${
|
||||
pkg.docsExtend.codepenDefaultTab
|
||||
}" frameborder="no" allowtransparency="true" allowfullscreen="true" loading="lazy">
|
||||
See the Pen <a href='https://codepen.io/omijs/pen/${
|
||||
pkg.docsExtend.codepen
|
||||
}'>OMIU Checkbox</a> by OMI
|
||||
(<a href='https://codepen.io/omijs'>@omijs</a>) on <a href='https://codepen.io'>CodePen</a>.
|
||||
</iframe>
|
||||
|
||||
${generateImportAndUsageDocs('en', {
|
||||
pkgName,
|
||||
tagName
|
||||
})}
|
||||
${generateAPIDocs('en', {
|
||||
props,
|
||||
defaultProps,
|
||||
eventMap
|
||||
})}
|
||||
`
|
||||
|
||||
// fs.writeFileSync(`../docs-src/src/docs/en/${name}.md`, enContent)
|
||||
|
||||
fs.writeFileSync(
|
||||
`./README.md`,
|
||||
enContent.replace(
|
||||
/<iframe[\s\S]*?<\/iframe>/,
|
||||
`- [→ CodePen](https://codepen.io/omijs/pen/${pkg.docsExtend.codepen})`
|
||||
)
|
||||
)
|
|
@ -0,0 +1,75 @@
|
|||
import { Language, t } from './locale'
|
||||
|
||||
/**
|
||||
* 生成 API 文档
|
||||
* @param locale
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function generateAPIDocs(
|
||||
locale: Language,
|
||||
params: {
|
||||
props: string
|
||||
defaultProps: string
|
||||
eventMap: any
|
||||
}
|
||||
) {
|
||||
const { props, defaultProps, eventMap } = params
|
||||
|
||||
let defaultPropsDocs = ''
|
||||
if (defaultProps) {
|
||||
defaultPropsDocs = `### ${t('defaultProps', locale)}
|
||||
|
||||
\`\`\`tsx
|
||||
${defaultProps}
|
||||
\`\`\`
|
||||
`
|
||||
}
|
||||
|
||||
let eventsDocs = ''
|
||||
if (eventMap) {
|
||||
eventsDocs = `### ${t('events', locale)}\n`
|
||||
Object.keys(eventMap).forEach((event) => {
|
||||
eventsDocs += `\n- ${event}`
|
||||
})
|
||||
}
|
||||
|
||||
return `
|
||||
## ${t('API', locale)}
|
||||
|
||||
### ${t('props', locale)}
|
||||
|
||||
\`\`\`tsx
|
||||
${props}
|
||||
\`\`\`
|
||||
|
||||
${defaultPropsDocs}
|
||||
${eventsDocs}`
|
||||
}
|
||||
|
||||
export function generateImportAndUsageDocs(
|
||||
locale: Language,
|
||||
params: {
|
||||
pkgName: string
|
||||
tagName: string
|
||||
}
|
||||
) {
|
||||
const { pkgName, tagName } = params
|
||||
return `## ${t('import', locale)}
|
||||
|
||||
\`\`\`js
|
||||
import '${pkgName}'
|
||||
\`\`\`
|
||||
|
||||
${t('importDescription', locale)}
|
||||
|
||||
\`\`\`html
|
||||
<script src="https://unpkg.com/${pkgName}"></script>
|
||||
\`\`\`
|
||||
|
||||
## ${t('usage', locale)}
|
||||
|
||||
\`\`\`html
|
||||
<${tagName}></${tagName}>
|
||||
\`\`\``
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
export type Language = 'zh' | 'en'
|
||||
|
||||
export const messages = {
|
||||
en: {
|
||||
defaultProps: 'Default Props',
|
||||
importDescription: 'Or use script tag to ref it.'
|
||||
},
|
||||
zh: {
|
||||
import: '导入',
|
||||
usage: '使用',
|
||||
props: '属性',
|
||||
defaultProps: '默认属性',
|
||||
importDescription: '或者直接 script 标签引入。'
|
||||
}
|
||||
}
|
||||
|
||||
export const t = (key: string, locale: Language) => {
|
||||
return messages[locale][key] || key.charAt(0).toUpperCase() + key.slice(1)
|
||||
}
|
||||
|
||||
export const en = (key: string) => t(key, 'en')
|
||||
export const zh = (key: string) => t(key, 'zh')
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* kekab-case to Pascal Case
|
||||
* @param name
|
||||
*/
|
||||
export function pascalCase(name: string) {
|
||||
return name
|
||||
.split('-')
|
||||
.map((item: string) => {
|
||||
return item.charAt(0).toUpperCase() + item.slice(1)
|
||||
})
|
||||
.join('')
|
||||
}
|
||||
|
||||
/**
|
||||
* extract string from content
|
||||
* @param startWith
|
||||
* @param str
|
||||
* @returns
|
||||
*/
|
||||
export function extract(startWith: string, str: string) {
|
||||
const start = str.indexOf(startWith)
|
||||
if (start === -1) return ''
|
||||
let end = start + startWith.length
|
||||
let stackCount = 1
|
||||
while (end < str.length) {
|
||||
if (str[end] === '}') {
|
||||
if (stackCount === 1) {
|
||||
break
|
||||
} else {
|
||||
stackCount--
|
||||
}
|
||||
} else if (str[end] === '{') {
|
||||
stackCount++
|
||||
}
|
||||
|
||||
end++
|
||||
}
|
||||
|
||||
return str.substring(start, end + 1)
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx"
|
||||
"src/**/*.tsx",
|
||||
],
|
||||
"exclude": []
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue