Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ node_modules
/dist
/dist-demo
/dist-site
# meta 派生产物:components.json 由 generate:meta 产出,各平台 llms 由 generate:llms 产出
# (build:site / build:taro:site 前自动生成),整个目录均为构建产物,不落库
# meta 派生产物:components.json 由 generate:meta 产出、semantic.json 由 generate:semantic 产出
# 各平台 llms 由 generate:llms 产出(build:site / build:taro:site 前自动生成),整个目录均为构建产物,不落库
/meta/
/release
/libs
Expand Down Expand Up @@ -66,4 +66,6 @@ pnpm-lock.*.yaml
.claude/commands/nutui-v4-upgrade.md

# Harmony CSS files
src/packages/**/*.harmony.css
src/packages/**/*.harmony.css

.playwright-cli/
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@
"build:demo:jmapp": "npm run checked && VITE_APP_PROJECT_ID=jmapp vite build --config vite.config.demo.ts",
"prebuild:taro:demo": "SKIPDD=1 pnpm run update:taro:entry",
"build:taro:demo": "npm run checked:taro && npm run generate:file:taro:pages && pnpm --dir ./packages/nutui-taro-demo build:h5",
"prebuild:site": "npm run generate:meta && npm run generate:llms",
"prebuild:site": "npm run generate:meta && npm run generate:semantic && npm run generate:llms",
"build:site": "vite build --config vite.config.site.mts",
"prebuild:taro:site": "npm run generate:meta && npm run generate:llms",
"prebuild:taro:site": "npm run generate:meta && npm run generate:semantic && npm run generate:llms",
"build:taro:site": "vite build --config vite.config.site.taro.mts && node ./scripts/rename.js",
"build:jdtaro:demo": "npm run checked:taro && npm run generate:file:taro:pages && JD=1 pnpm --dir ./packages/nutui-taro-demo build:h5",
"build:taro:demo:jmapp": "npm run checked:taro && VITE_APP_PROJECT_ID=jmapp npm run generate:file:taro:pages && pnpm --dir ./packages/nutui-taro-demo build:jmapp h5",
Expand All @@ -90,6 +90,7 @@
"generate:props_json": "PROPS_JSON=true node scripts/build-comments-to-dts.mjs",
"generate:meta": "node scripts/build-meta.mjs",
"generate:llms": "node scripts/build-llms.mjs",
"generate:semantic": "node scripts/build-semantic.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
43 changes: 43 additions & 0 deletions scripts/build-llms.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { fileURLToPath, pathToFileURL } from 'url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const ROOT = path.resolve(__dirname, '..')
const META_PATH = path.join(ROOT, 'meta/components.json')
const SEMANTIC_PATH = path.join(ROOT, 'meta/semantic.json')
const OUTPUT_DIR = path.join(ROOT, 'meta')

export const SITE_ORIGIN = 'https://nutui.jd.com'
Expand Down Expand Up @@ -45,6 +46,16 @@ export function loadMeta() {

const siteUrl = (platform) => `${SITE_ORIGIN}${PLATFORMS[platform].base}`

// 尝试读 semantic.json(需先 npm run generate:semantic)。未生成时返回 null,
// llms 产物据此跳过 semantic 入口/链接而非报错。直接读 JSON 避免与 build-semantic.mjs 循环依赖。
function tryLoadSemantic() {
try {
return JSON.parse(fs.readFileSync(SEMANTIC_PATH, 'utf-8'))
} catch {
return null
}
}

// 仅纳入在该平台有中文文档的组件(= show:true 的展示组件),按 categories 的 nav 顺序输出。
function docComponents(meta, cnKey) {
const list = []
Expand All @@ -62,6 +73,7 @@ export function generateLlmsTxt(meta, platform = 'h5') {
const cnKey = conf.langDocKey.cn
const url = siteUrl(platform)
const groups = docComponents(meta, cnKey)
const semantic = tryLoadSemantic()
const lines = []
lines.push(`# NutUI React - 京东风格轻量级移动端 React 组件库${conf.titleSuffix}`)
lines.push('')
Expand All @@ -79,6 +91,12 @@ export function generateLlmsTxt(meta, platform = 'h5') {
if (conf.langDocKey.en) {
lines.push(`- [Full Documentation (English, single file)](${url}/llms-full.txt)`)
}
if (semantic) {
lines.push(`- [全部组件样式结构(中文,单文件)](${url}/llms-semantic-cn.txt)`)
if (conf.langDocKey.en) {
lines.push(`- [Component Style Structure (English, single file)](${url}/llms-semantic.txt)`)
}
}
lines.push('')

for (const { category, comps } of groups) {
Expand All @@ -90,6 +108,24 @@ export function generateLlmsTxt(meta, platform = 'h5') {
}
lines.push('')
}

// per-component 语义文档分区(仅当 semantic.json 已生成)。列出每个有语义数据的组件的 semantic.md 链接。
if (semantic) {
lines.push('## 样式结构 (Semantic)')
lines.push('')
lines.push(
'每个组件的 `semantic.md` 列出其渲染产物可用的 CSS class 与 CSS 变量,供自定义样式 / 主题覆盖时精确定位。'
)
lines.push('')
for (const { comps } of groups) {
for (const c of comps) {
if (!semantic.components[c.id]) continue
const label = c.cName ? `${c.name} ${c.cName}` : c.name
lines.push(`- [${label} Semantic](${url}/components/${c.id}/semantic.md)`)
}
}
lines.push('')
}
return `${lines.join('\n').trimEnd()}\n`
}

Expand All @@ -102,6 +138,9 @@ export function generateLlmsFull(meta, platform = 'h5', lang = 'cn') {
? '# NutUI React - Full Component Documentation'
: `# NutUI React - 全部组件文档${conf.titleSuffix}`
const summary = lang === 'en' ? SUMMARY_EN : SUMMARY
const url = siteUrl(platform)
const semantic = tryLoadSemantic()
const semanticHeading = lang === 'en' ? 'Semantic DOM' : '样式结构 (Semantic DOM)'
const parts = [title, '', `> ${summary}`, '']
for (const cat of meta.categories) {
for (const id of cat.components) {
Expand All @@ -112,6 +151,10 @@ export function generateLlmsFull(meta, platform = 'h5', lang = 'cn') {
if (!fs.existsSync(abs)) continue
parts.push('---', '')
parts.push(fs.readFileSync(abs, 'utf-8').trim())
// 组件语义文档链接(不内联正文,与 llms-full 的文档主体分离,同 Ant Design 组织方式)。
if (semantic && semantic.components[id]) {
parts.push('', `## ${semanticHeading}`, '', `${url}/components/${id}/semantic.md`)
}
parts.push('')
}
}
Expand Down
Loading
Loading