消费方迁移清单(消费项目 → admin 包)
记录把消费项目从"复制 admin-shared 副本"切换到"依赖 admin 包"的做法与已验证结论。迁移已在 ug-console 上完整执行并通过验证,按本清单可复现。
结论先行:不需要发布,也不需要合并仓库
单实例问题的根因不在依赖形态,而在渲染层包把 UI 与框架库写成了普通依赖:
// 错误:file: 安装时 bun 会为包里再复制一份
"dependencies": { "@ug666/ui-react": "file:...", "react": "^19.0.0" }
// 正确:库对宿主提供的能力一律 peer
"dependencies": {},
"peerDependencies": { "@ug666/ui-react": "^0.3.0", "react": "^19.0.0" }
改完之后消费方的 node_modules/.bun 里 UI 运行时只剩一份,file: 依赖可以直接用,不需要别名、不需要发布 registry、不需要合并 workspace。
迁移步骤
1. 依赖
// 消费方 apps/<端>/package.json
"dependencies": {
"@ug666/admin-core": "file:../../ug-admin/packages/admin-core",
"@ug666/admin-react": "file:../../ug-admin/packages/admin-react"
}
file: 路径按实际相对位置写;若包内还有跨包引用,在根 package.json 的 overrides 里同样指向同一路径。
2. 分类,不要按文件名批量替换
消费方的旧副本里往往混着两类东西,必须先分清再改:
| 类别 | 内容 | 处理 |
|---|---|---|
| 框架通用 | 数据契约、认证、权限、品牌、偏好、平台信息、资源常量、路由类型、测试工具 | 改引用 @ug666/admin-core/* |
| 消费方自有 | 页面注册表(自己的产品页面清单)、模块与页签装配、首页入口、会话复核、统计 DTO | 搬到消费方本地目录(如 apps/<端>/src/console/),继续用自己那份 |
按文件名映射会踩坑:消费方的 admin-pages 通常绑定自己的页面表,换成 admin-core 的会让它拿到模板页面集合,产品目录与路由用例立刻失败。
3. 页面模式与组件
消费方自写的 AdminPage / AdminListPage / AdminFormPage 副本删除,改引用 @ug666/admin-react/patterns/*(Vue 端为 @ug666/admin-vue/patterns/*.vue)。样式入口用 @ug666/admin-core/styles/app.css。
4. 编译期常见差异
AdminIconKey可能多了新值(如dictionaries),图标映射表要补齐- 页面 module 判定函数的入参放宽为字符串,避免与 admin-core 的
AdminModuleId联合不兼容 - 数据适配器的错误判定不要用
instanceof AdminDataError(跨包会有两份类),按code字段判定
5. 验证
bun run typecheck
bun run test
bun run build
外加用 runAdminDataProviderConformance(provider, { writable: false }) 校验适配器契约。
实测记录(2026-11,ug-console)
| 策略 | 安装 | 类型 | 页面渲染 |
|---|---|---|---|
file: + 渲染层把 core 声明为 peer,UI 仍为普通依赖 |
✅ | ✅ | ❌ 空白 |
再加 resolve.dedupe(react / ui-react / admin-core) |
✅ | ✅ | ❌ 空白 |
再把 UI 与框架库改为 peerDependencies |
✅ | ✅ | ✅ 正常 |
原因:file: 依赖以复制快照装进 node_modules/.bun/@ug666+admin-core@file+…,包内部 import "@ug666/ui-react" 会从该副本目录向上解析,拿到与消费方不同的那份 UI 运行时;React 上下文因此断开,页面渲染为空。把 UI 与框架库声明为 peer 后,副本里不再自带运行时,解析自然回落到消费方那一份。
迁移完成后 ug-console 侧验证:类型检查 0 错误、16 个测试文件通过、生产构建成功。