# CODEBUDDY.md This file provides guidance to CodeBuddy Code when working with code in this repository. ## Overview G3Soft frontend infrastructure — a pnpm monorepo holding a self-built **Vue 3 component library** plus a **VitePress documentation site**. - `packages/ui` (`@g3soft/ui`) — component library, published to a private npm registry. One directory per component under `src//`. - `packages/tokens` (`@g3soft/tokens`) — design tokens as plain CSS (`--g3-*` variables), shared by the library and the docs site. - `docs` (`@g3soft/docs`) — VitePress docs site (default theme). `private: true`, never published. 组件文档(示例 + API)全部手写在 `docs/content/ui/<分类>/<组件>.md`。 Requires Node >= 20.19 and pnpm 11 (see `packageManager` in root `package.json`). ## Commands ```bash pnpm install pnpm dev # start docs site (http://localhost:5173); live-reloads packages/ui via alias pnpm build # build all packages under packages/** (component lib -> dist) pnpm build:docs # build docs static site -> docs/.vitepress/dist pnpm preview:docs # preview the built docs site ``` Deploying docs to a subpath: ```bash DOCS_BASE_URL=/docs/ pnpm build:docs ``` Releasing the component library (changesets): ```bash pnpm changeset # record the change pnpm version # bump versions + generate CHANGELOG pnpm release # build + publish to the private registry ``` `packages/ui` runs `publint` via `prepublishOnly` to validate package structure (`exports`/`files` consistency). **Testing:** 三层测试(vitest + happy-dom / Playwright)见下方「测试与自检」:`pnpm test`、`pnpm test:e2e`、`pnpm verify`。 ### Running a single component's checks 没有 per-component 的 lint 脚本。类型检查用 `pnpm --filter @g3soft/ui typecheck`(`vue-tsc --noEmit`)—— **别指望 `pnpm build` 兜底**:它会把 TS 错误打出来,却照样 exit 0 并产出 d.ts(实测漏声明两个 prop 时构建仍报「✓ built in 7s」)。单跑一个测试文件:`pnpm --filter @g3soft/ui exec vitest run src/date/date-utils.test.ts`。 ## Architecture ### Two independent pipelines The docs site and the component library are deliberately decoupled: | | Docs site | Component package | |---|---|---| | Published | No (`private: true`) | Yes (private npm registry) | | Versioning | None | changesets (`ignore: ["@g3soft/docs"]`) | | Build | `pnpm build:docs` | `pnpm build` | | Output | `docs/.vitepress/dist` (static) | `packages/ui/dist` (ESM + d.ts) | | Dep boundary | VitePress lives only in the `docs` package | only `vue` (peer) + `@g3soft/tokens` | VitePress-related deps appear **only** in `docs/package.json`; the library's dependency tree has none of it. changesets' `ignore` keeps the docs site out of version tags. ### Component library build (`packages/ui`) `vite.config.ts` builds ESM + type declarations. Critical points: - `vue` is marked `external` — never bundle Vue, or consumers get duplicate instances. - `preserveModules` keeps the `src` structure so consumers can tree-shake. - `vite-plugin-dts` 产出**逐文件 d.ts + `dist/index.d.ts`(re-export barrel)**,与 `exports.types` 对齐;刻意不打包成单文件(那要 `bundleTypes` + `@microsoft/api-extractor` peer)。注意 v5 里 `outDir` / `rollupTypes` 这类**旧选项名会被静默忽略**,改完配置跑 `pnpm typecheck` 才看得见。 - `src/index.ts` is the public entry: it re-exports every component plus its types, and exports the optional `G3UI` install plugin for whole-library registration. ### Docs site (`docs`) - VitePress with the **default theme**; config lives at `docs/.vitepress/config.mts` (`srcDir: 'content'`, so `docs/content/` is the site root). - Navigation/sidebar are declared in `config.mts` (`themeConfig.nav` / `themeConfig.sidebar`), replacing Docus's `.navigation.yml` + `navigation.sub`. Search is VitePress's built-in local search (no native module). - `vite.resolve.alias` points `@g3soft/ui` **directly at `packages/ui/src`**, and `@g3soft/tokens` at `packages/tokens/dist/index.css`, so the docs site can develop against the library without building it. Editing `packages/ui` hot-reloads the docs immediately (tokens still need `pnpm --filter @g3soft/tokens build`). - Deploy base path comes from `DOCS_BASE_URL`; site URL (sitemap hostname) from `DOCS_SITE_URL` — never hardcoded. - `docs/.vitepress/theme/` holds the theme: `index.ts` (extends default theme, imports tokens CSS), `Layout.vue` (syncs VitePress dark mode → `data-g3-theme`). Demo 容器由 `vitepress-demo-plugin` 提供(见下)。 - Examples are embedded with `` (provided by `vitepress-demo-plugin`, registered in `config.mts` via `markdown.config`, with `demoDir` pointing at `docs/examples`). ### 组件文档写作约定(手写,不生成) 组件文档在 `docs/content/ui/<分类>/<组件>.md` 里**手写全文**:正文说明 + `` + 手写的 API 表格(Props / Events / Slots / Exposed / 类型定义 / 样式变量 / 实现说明)。 约定: - **一个功能一个示例**:示例文件按功能命名(`basic` / `variant` / `loading` / `remote` …),不要写「大杂烩」示例;示例内用注释说明「这个功能怎么用」。 - 示例里**不要在 setup 顶层使用 `window` / `document`**(文档站是 SSR 预渲染的),需要浏览器 API 时放到 `onMounted`。 - 改组件的 props / events / slots 时,同步改对应 md 的 API 表格——没有生成器兜底,忘改就是文档错误。 - 分类目录:`usage` / `general` / `form` / `overlay` / `feedback` / `data`;侧边栏分组在 `docs/.vitepress/config.mts` 的 `themeConfig.sidebar` 里维护——**新增组件页时忘加这一条,页面就不会出现在导航里**。 ### Design tokens (`packages/tokens`) - `src/index.css` imports `tokens.css` (light/default) and `dark.css`. Consumed as `import '@g3soft/tokens'`. - Dark theme activates via `html[data-g3-theme='dark']` (`document.documentElement.dataset.g3Theme = 'dark'`). - Re-theming/customer customization = overriding same-named `--g3-*` variables, no component changes. ## Conventions (must follow) - **No `scoped` in component `