消费方迁移清单(消费项目 → 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 个测试文件通过、生产构建成功。