feat: add docs gen script for omi-cli component template

This commit is contained in:
YunYouJun 2021-09-16 01:19:48 +08:00
parent c0b7affb03
commit 8f1672c4e7
9 changed files with 393 additions and 28 deletions

View File

@ -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
```

View File

@ -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

View File

@ -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

View File

@ -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": [

View File

@ -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})`
)
)

View File

@ -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}>
\`\`\``
}

View File

@ -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')

View File

@ -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)
}

View File

@ -23,7 +23,7 @@
},
"include": [
"src/**/*.ts",
"src/**/*.tsx"
"src/**/*.tsx",
],
"exclude": []
}