Files
workspace/code/g3soft-libs/README.md
T
2026-10-13 17:29:55 +08:00

120 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# g3soft-libs
G3Soft 技术基础设施:**自研 Vue 3 组件库** + **Docus 技术文档站**(面向整体技术体系,不限于前端),pnpm monorepo 管理。
## 目录结构
```
g3soft-libs/
├── pnpm-workspace.yaml # workspace 声明 + catalog 统一版本 + 构建脚本白名单
├── packages/
│ ├── ui/ # 组件库(发布到 npm 私库)
│ │ ├── src/button/ # 一组件一目录
│ │ └── vite.config.ts # 产出 ESM + 类型声明
│ └── tokens/ # 设计变量,组件库与文档站共用
├── docs/ # 文档站(private,不发布)
│ ├── nuxt.config.ts # Docus Layer + alias 直连 packages 源码
│ ├── content/ # Markdown 内容:组件正文 + 手写 API 表格
│ ├── examples/ # 可运行示例,一个功能一个文件,按组件分目录
│ └── app/components/content # Demo.vue(可在 md 中直接使用)
```
## 环境要求
- Node.js >= 20.19
- pnpm 11(`better-sqlite3` 是 Docus 全文搜索依赖的原生模块,已在 `allowBuilds` 中放行)
## 安装
```bash
pnpm install
```
## 开发
```bash
pnpm dev
```
启动技术文档站:端口默认从 3000 起,被占用时自动向后选空闲端口(见 `docs/scripts/dev.mjs`);控制台会打印本机(`http://localhost:<port>`)与局域网访问地址。组件源码通过 alias 直连,改 `packages/ui` 会即时热更。
## 构建
```bash
pnpm build # 构建 packages/*(组件库产出 dist)
pnpm build:docs # 构建文档站静态文件
```
文档站静态产物在 `docs/.output/public`,可直接部署到任意静态托管。
### 改完组件库,怎么让业务方生效
`g3soft-erp` 通过 `overrides` link 到本仓库的 `packages/ui`,**消费的是构建产物 `dist/`**(`exports` 指向 `./dist/index.js` 与 `./dist/style.css`),不是源码。所以改了 `packages/ui/src` 之后不重新 build,业务方一点变化都看不到。
关键在于**不能边跑 ERP dev server 边构建**。ERP 的 Vite 监视着 `dist/`,而 `vite build` 会先清空再逐个写回产物文件,于是:
1. 每个产物文件被重写都触发一次 `page reload`,浏览器反复刷新;
2. 构建中途 `dist/style.css` 会**短暂不存在**,而 ERP 的 `src/styles/index.scss` 里有 `@use '@g3soft/ui/style.css';`,Sass 解析时文件已经没了 —— dev server 进程直接崩溃:
```
[vite] Internal server error: [sass] ENOENT: no such file or directory,
open 'D:\workspace\code\g3soft-libs\packages\ui\dist\style.css'
╷
9 │ @use '@g3soft/ui/style.css';
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
╵
src\styles\index.scss 9:1 root stylesheet
```
随后是 `ELIFECYCLE Command failed with exit code 4294967295.`
还有更隐蔽的一种:server 没崩,但缓存到了**写入中途**的模块图,页面白屏、控制台报 `Failed to resolve import "./tooltip/Tooltip.js" from ".../dist/index.js"`。此时 `dist` 盘上的产物其实是完整的,问题纯粹在 Vite 缓存。
**因此顺序只能是「先停、再构建、后启动」**:
1. 停掉 ERP 的 dev server(占用 5090 端口)
2. 在本仓库执行 `pnpm --filter @g3soft/ui build`
3. 在 `g3soft-erp/web` 下执行 `pnpm dev` 重新启动
若怀疑是缓存问题(白屏、找不到模块),额外删掉 `g3soft-erp/web/node_modules/.vite` 再启动即可。改 `packages/tokens` 同理 —— 它也要 build,且要在业务方 dev server 停掉时做。
> 这跟 `pnpm dev`(文档站)无关:文档站通过 alias 直连 `packages/ui/src`,改源码即时热更,不需要也不应该为它重新构建组件库。
### 部署到子路径
文档站支持挂载到子路径,构建时通过环境变量指定:
```bash
NUXT_APP_BASE_URL=/docs/ pnpm build:docs
```
## 发布组件包
组件库走 changesets 管理版本:
```bash
pnpm changeset # 记录本次改动
pnpm version # 生成版本号与 CHANGELOG
pnpm release # 构建并发布到私库
```
`packages/ui` 的 `prepublishOnly` 会执行 `publint` 校验包结构(`exports`、`files` 是否自洽)。
## 两条链路为什么互不干扰
| | 文档站 | 组件包 |
|---|---|---|
| 是否发布 | 否(`private: true`) | 是(npm 私库) |
| 版本管理 | 无 | changesets(已 `ignore: ["@g3soft/docs"]`) |
| 构建命令 | `pnpm build:docs` | `pnpm build` |
| 产物 | `docs/.output/public`(静态) | `packages/ui/dist`(ESM + d.ts) |
| 依赖边界 | Docus / Nuxt / Tailwind 只在 `docs` 包 | 只有 `vue`(peer) 与 `@g3soft/tokens` |
关键点:Nuxt 相关的依赖**只出现在 `docs/package.json`**,组件库的依赖树里没有任何文档站的东西;changesets 的 `ignore` 保证打 tag 发版时不会带上文档站。
## 约定
- 组件样式**不写 `scoped`**,用 `g3-` 前缀 + BEM,颜色尺寸一律引用 `--g3-*` 变量。
- 组件 API 文档**手写在 md 里**(Props / Events / Slots / 类型定义 / 样式变量 / 实现说明);改了 props/events/slots 记得同步改文档。
- 示例放 `docs/examples/<组件名>/<示例名>.vue`,在 md 中用 `::demo{name="<组件名>/<示例名>"}` 引用;**一个功能一个示例**,示例里不要在 setup 顶层用 `window` / `document`(文档站是 SSR 预渲染)。