component-auto-docs 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@ App 内组件详情页默认使用 Tab 分区:
|
|
|
40
40
|
- `docs/ai/components.quality.json`:文档质量报告。
|
|
41
41
|
- `src/docs/data.json`:App 内文档首页数据。
|
|
42
42
|
- `src/docs/components/*/data.json`:单组件详情页数据。
|
|
43
|
+
- `src/docs/data.js`、`src/docs/components/*/data.js`:App/小程序运行时使用的数据模块,避免部分小程序编译链把 JSON 字段提升成同名顶层变量。
|
|
43
44
|
- `src/docs/components/*/index.vue`:单组件交互文档页。
|
|
44
45
|
|
|
45
46
|
## 快速开始
|
|
@@ -117,6 +118,7 @@ DOCS_CONFIG=./docs.config.mjs pnpm exec component-auto-docs gen
|
|
|
117
118
|
- `componentRoot`:组件目录,默认 `src/components`。
|
|
118
119
|
- `metaFileName`:组件元数据文件名,默认 `docs.meta.json`。
|
|
119
120
|
- `output`:Markdown、AI 文档、页面数据和质量报告输出位置。
|
|
121
|
+
- `pageDataModuleFileName`:单组件页面运行时数据模块文件名,默认 `data.js`。
|
|
120
122
|
- `routes`:是否自动写入 `pages.json`,以及文档路由前缀、插入锚点、标题后缀。
|
|
121
123
|
- `runtime`:自动文档页使用的页面壳、hook 和组件导入别名。
|
|
122
124
|
- `quality`:质量检查规则,例如是否要求 App 内文档页存在。
|
|
@@ -20,6 +20,7 @@ const defaultDocsConfig = {
|
|
|
20
20
|
markdownDir: 'docs/components',
|
|
21
21
|
pageDataRoot: 'src/docs/components',
|
|
22
22
|
indexDataFile: 'src/docs/data.json',
|
|
23
|
+
pageDataModuleFileName: 'data.js',
|
|
23
24
|
catalogFile: 'components.catalog.json',
|
|
24
25
|
aiIndexFile: 'components.index.md',
|
|
25
26
|
llmsFile: 'llms.txt',
|
|
@@ -158,6 +159,57 @@ function writeText(filePath, content) {
|
|
|
158
159
|
fs.writeFileSync(filePath, `${content.trimEnd()}\n`);
|
|
159
160
|
}
|
|
160
161
|
|
|
162
|
+
function hashText(text) {
|
|
163
|
+
let hash = 5381;
|
|
164
|
+
|
|
165
|
+
for (const char of String(text)) {
|
|
166
|
+
hash = (hash * 33) ^ char.codePointAt(0);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return (hash >>> 0).toString(36);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function toDataModuleIdentifier(name, fallback) {
|
|
173
|
+
const words = String(name).match(/[A-Za-z0-9]+/g) || [];
|
|
174
|
+
const base = words
|
|
175
|
+
.map((word, index) => {
|
|
176
|
+
const lower = word.toLowerCase();
|
|
177
|
+
return index === 0 ? lower : lower.charAt(0).toUpperCase() + lower.slice(1);
|
|
178
|
+
})
|
|
179
|
+
.join('');
|
|
180
|
+
const identifierBase = base && /^[A-Za-z_$]/.test(base) ? base : fallback;
|
|
181
|
+
|
|
182
|
+
return `${identifierBase}Data_${hashText(name)}`;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function serializeJsValue(value) {
|
|
186
|
+
return JSON.stringify(value, null, 2)
|
|
187
|
+
.replace(/\u2028/g, '\\u2028')
|
|
188
|
+
.replace(/\u2029/g, '\\u2029');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function renderDataModule(data, identifier) {
|
|
192
|
+
return `// @generated by ${generatedBy}. Keep this file in sync by running docs:gen.
|
|
193
|
+
const ${identifier} = ${serializeJsValue(data)};
|
|
194
|
+
|
|
195
|
+
export default ${identifier};
|
|
196
|
+
`;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function writeDataModule(filePath, data, identifier) {
|
|
200
|
+
writeText(filePath, renderDataModule(data, identifier));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function getIndexDataModuleFile() {
|
|
204
|
+
const parsed = path.parse(indexDataFile);
|
|
205
|
+
|
|
206
|
+
return path.join(parsed.dir, `${parsed.name}.js`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function getPageDataModuleFileName() {
|
|
210
|
+
return docsConfig.output.pageDataModuleFileName || 'data.js';
|
|
211
|
+
}
|
|
212
|
+
|
|
161
213
|
function normalizeTypeText(typeText) {
|
|
162
214
|
return typeText
|
|
163
215
|
.replace(/\s+/g, ' ')
|
|
@@ -1532,6 +1584,7 @@ function renderAutoDocPage(componentName, componentFile) {
|
|
|
1532
1584
|
const importName = componentName
|
|
1533
1585
|
.replace(/(^|-)(\w)/g, (_, __, char) => char.toUpperCase())
|
|
1534
1586
|
.replace(/[^\w]/g, '');
|
|
1587
|
+
const dataModuleImport = `./${getPageDataModuleFileName()}`;
|
|
1535
1588
|
const {
|
|
1536
1589
|
componentDocPageImport,
|
|
1537
1590
|
autoDocHookImport,
|
|
@@ -1545,7 +1598,7 @@ function renderAutoDocPage(componentName, componentFile) {
|
|
|
1545
1598
|
import ${componentDocPageName} from '${componentDocPageImport}';
|
|
1546
1599
|
import { ${autoDocHookName} } from '${autoDocHookImport}';
|
|
1547
1600
|
import ${importName} from '${componentImportBase}/${componentName}/${fileName}';
|
|
1548
|
-
import doc from '
|
|
1601
|
+
import doc from '${dataModuleImport}';
|
|
1549
1602
|
|
|
1550
1603
|
const {
|
|
1551
1604
|
propControls,
|
|
@@ -1618,6 +1671,7 @@ const {
|
|
|
1618
1671
|
v-else-if="isArrayProp(prop) || isObjectProp(prop)"
|
|
1619
1672
|
:value="propControls[prop.name]"
|
|
1620
1673
|
class="control-textarea"
|
|
1674
|
+
:maxlength="-1"
|
|
1621
1675
|
:placeholder="prop.description || prop.name"
|
|
1622
1676
|
@input="setControlValue(prop.name, $event.detail.value)"
|
|
1623
1677
|
/>
|
|
@@ -1650,10 +1704,11 @@ ${renderGeneratedControlStyles()}
|
|
|
1650
1704
|
|
|
1651
1705
|
function renderGenericDocPage() {
|
|
1652
1706
|
const { componentDocPageImport, componentDocPageName } = docsConfig.runtime;
|
|
1707
|
+
const dataModuleImport = `./${getPageDataModuleFileName()}`;
|
|
1653
1708
|
|
|
1654
1709
|
return `<script setup lang="ts">
|
|
1655
1710
|
import ${componentDocPageName} from '${componentDocPageImport}';
|
|
1656
|
-
import doc from '
|
|
1711
|
+
import doc from '${dataModuleImport}';
|
|
1657
1712
|
</script>
|
|
1658
1713
|
|
|
1659
1714
|
<template>
|
|
@@ -2128,13 +2183,24 @@ function main() {
|
|
|
2128
2183
|
writeJson(path.join(aiDocsDir, docsConfig.output.catalogFile), catalog);
|
|
2129
2184
|
writeText(path.join(aiDocsDir, docsConfig.output.aiIndexFile), renderAiIndex(catalog));
|
|
2130
2185
|
writeText(path.join(aiDocsDir, docsConfig.output.llmsFile), renderLlmsTxt(catalog));
|
|
2131
|
-
|
|
2186
|
+
const pageIndex = buildPageIndex(components);
|
|
2187
|
+
writeJson(indexDataFile, pageIndex);
|
|
2188
|
+
writeDataModule(
|
|
2189
|
+
getIndexDataModuleFile(),
|
|
2190
|
+
pageIndex,
|
|
2191
|
+
toDataModuleIdentifier(docsConfig.projectName || 'docs-index', 'docsIndex'),
|
|
2192
|
+
);
|
|
2132
2193
|
const qualityReport = collectQualityReport(components);
|
|
2133
2194
|
writeJson(path.join(aiDocsDir, docsConfig.output.qualityFile), qualityReport);
|
|
2134
2195
|
|
|
2135
2196
|
for (const component of components) {
|
|
2136
2197
|
writeText(path.join(markdownDocsDir, `${component.name}.md`), renderComponentMarkdown(component));
|
|
2137
2198
|
writeJson(path.join(pageDataRoot, component.name, 'data.json'), component);
|
|
2199
|
+
writeDataModule(
|
|
2200
|
+
path.join(pageDataRoot, component.name, getPageDataModuleFileName()),
|
|
2201
|
+
component,
|
|
2202
|
+
toDataModuleIdentifier(component.name, 'componentDoc'),
|
|
2203
|
+
);
|
|
2138
2204
|
}
|
|
2139
2205
|
|
|
2140
2206
|
console.log(`Generated component docs for ${components.length} component(s): ${components.map((item) => item.name).join(', ')}`);
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "component-auto-docs",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Component docs automation CLI for uni-app component libraries.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"component-auto-docs": "bin/component-auto-docs.mjs"
|
|
8
8
|
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"release:dry-run": "npm publish --dry-run",
|
|
11
|
+
"release": "npm publish"
|
|
12
|
+
},
|
|
9
13
|
"files": [
|
|
10
14
|
"bin",
|
|
11
15
|
"core",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
生成产物分为三类:
|
|
13
13
|
|
|
14
14
|
- 人类阅读:`docs/components/*.md`。
|
|
15
|
-
- App 内页面:`src/docs/data.json`、`src/docs/components/*/data.json`、`src/docs/components/*/index.vue`。
|
|
15
|
+
- App 内页面:`src/docs/data.json`、`src/docs/data.js`、`src/docs/components/*/data.json`、`src/docs/components/*/data.js`、`src/docs/components/*/index.vue`。
|
|
16
16
|
- AI/检索:`docs/ai/components.catalog.json`、`docs/ai/components.index.md`、`docs/ai/llms.txt`、`docs/ai/components.quality.json`。
|
|
17
17
|
|
|
18
18
|
## 新组件接入
|
|
@@ -80,6 +80,7 @@ pnpm exec component-auto-docs scaffold --force
|
|
|
80
80
|
- `componentRoot`:组件目录,例如 `src/components`。
|
|
81
81
|
- `metaFileName`:组件元数据文件名,默认 `docs.meta.json`。
|
|
82
82
|
- `output`:AI 文档、Markdown、页面数据和质量报告输出位置。
|
|
83
|
+
- `output.pageDataModuleFileName`:单组件页面运行时数据模块文件名,默认 `data.js`。
|
|
83
84
|
- `routes`:是否自动写入 `pages.json`、文档入口路由、组件文档路由前缀、插入锚点和标题后缀。
|
|
84
85
|
- `runtime`:自动文档页使用的页面壳、hook 和组件导入别名。
|
|
85
86
|
- `quality`:质量检查是否要求 App 内文档页,以及页面壳识别规则。
|
|
@@ -13,6 +13,7 @@ export default {
|
|
|
13
13
|
markdownDir: 'docs/components',
|
|
14
14
|
pageDataRoot: 'src/docs/components',
|
|
15
15
|
indexDataFile: 'src/docs/data.json',
|
|
16
|
+
pageDataModuleFileName: 'data.js',
|
|
16
17
|
catalogFile: 'components.catalog.json',
|
|
17
18
|
aiIndexFile: 'components.index.md',
|
|
18
19
|
llmsFile: 'llms.txt',
|