Files
workspace/code/g3soft-libs
2026-10-13 22:32:50 +08:00
..
u
2026-10-13 22:32:50 +08:00
u
2026-10-08 22:38:34 +08:00
u
2026-10-13 22:32:50 +08:00
u
2026-10-13 22:32:50 +08:00
u
2026-10-09 22:05:02 +08:00
u
2026-10-09 22:05:02 +08:00
u
2026-10-13 17:29:55 +08:00
u
2026-10-09 17:32:14 +08:00
u
2026-10-12 22:25:41 +08:00
u
2026-10-09 17:32:14 +08:00
u
2026-10-13 17:29:55 +08:00
u
2026-10-08 22:38:34 +08:00
2026-10-07 22:01:17 +08:00

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 中放行)

安装

pnpm install

开发

pnpm dev

启动技术文档站:端口默认从 3000 起,被占用时自动向后选空闲端口(见 docs/scripts/dev.mjs);控制台会打印本机(http://localhost:<port>)与局域网访问地址。组件源码通过 alias 直连,改 packages/ui 会即时热更。

构建

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,改源码即时热更,不需要也不应该为它重新构建组件库。

部署到子路径

文档站支持挂载到子路径,构建时通过环境变量指定:

NUXT_APP_BASE_URL=/docs/ pnpm build:docs

发布组件包

组件库走 changesets 管理版本:

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 预渲染)。