Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/194 Co-authored-by: kdletters <kdletters@qq.com> Co-committed-by: kdletters <kdletters@qq.com>
7.0 KiB
npm workspaces 统一依赖边界
更新时间:2026-08-21
目标
Genarrative 的 JavaScript 工程统一使用 npm workspaces。仓库只提交根 package-lock.json,开发、CI、Jenkins 和容器构建都从仓库根执行一次干净安装;各 App、内部包和工具仍由自己的 package.json 声明直接依赖和脚本。
本方案只迁移包管理与依赖边界,不切换 pnpm,不改变 Cargo workspace、SpacetimeDB schema、前后端 DTO 或业务运行时。
Workspace 范围
根 package.json 固定声明:
{
"packageManager": "npm@10.9.7",
"workspaces": [
"apps/admin-web",
"apps/ai-game-creator-shell",
"apps/desktop-shell",
"apps/mobile-shell",
"apps/preview-deployer-web",
"packages/image-canvas-core",
"packages/image-canvas-react",
"packages/shared",
"tools/spine-json-export-validator"
]
}
当前纳入:
apps/admin-webapps/ai-game-creator-shellapps/desktop-shellapps/mobile-shellapps/preview-deployer-webpackages/image-canvas-corepackages/image-canvas-reactpackages/sharedtools/spine-json-export-validator
.rag/runtime、.worktrees/、tmp/、构建目录和各级 node_modules 不属于 workspace。RAG 继续保持独立、gitignored 的本地运行时,不进入根依赖。
Manifest 与依赖所有权
- 根 manifest 只声明根 H5、仓库级脚本和统一测试/格式化工具的直接依赖,不再为 Mobile、AGC 或工具重复声明其专属依赖。
- 每个 App 在自己的 manifest 声明运行时直接依赖;测试只由根统一 runner 承担的工具可以留在根,App 自己提供测试脚本时必须声明其直接测试依赖。
@genarrative/image-canvas-react必须显式依赖@genarrative/image-canvas-core;主站和 AGC 必须显式声明它们直接消费的内部画布包。- npm
10.9.7不支持依赖值workspace:*。内部 workspace 依赖使用匹配本地包版本的普通 semver,例如"@genarrative/image-canvas-core": "0.1.0";npm 在根安装时自动生成本地link。 - npm 默认提升依赖,统一根
node_modules中存在某包不代表根 H5 拥有该依赖。归属门禁必须检查对应 workspace manifest 和根 lock 中的 workspace package entry,不能按统一 lock 的全局node_modules/*条目判断归属。
packages/shared 本次纳入统一安装和 lock,但不顺手重写现有源码 import;后续若要把所有相对源码引用改为 @genarrative/shared,需先补完整 exports/build 合同并单独实施。
唯一 Lockfile
- 唯一权威 npm lockfile 为根
package-lock.json。 - 删除
apps/ai-game-creator-shell/package-lock.json与tools/spine-json-export-validator/package-lock.json。 - 新增或修改任一 workspace 依赖后,只能从仓库根使用固定 npm 版本更新根 lock。
- 仓库门禁必须校验 workspace 清单、固定
packageManager、根 lock 的 workspace package/link 条目,并拒绝受管 workspace 再提交嵌套package-lock.json或npm-shrinkwrap.json。 - optional dependency、平台二进制和 bundled dependency 仍由根 lock 完整记录;Linux 生成 lock 后仍需 Windows/macOS 对应构建门禁,不能把单平台安装等同于跨平台通过。
安装与脚本
标准安装入口:
npm ci
开发者首次拉取或主动更新依赖时可使用根 npm install。Husky 的 prepare 只在根执行一次;各 workspace 不重复安装 hook。
现有 npm run agc、npm run mobile-shell:*、npm run desktop-shell:*、npm run preview-deployer:web:* 和 npm run spine-export-validator:* 等对外入口保持名称稳定。内部可继续使用 npm --prefix,或使用 npm run <script> --workspace=<name>;无论哪种写法,都必须保证 Expo、EAS 和 Tauri 命令在目标 App cwd 中执行。
AGC 的 TypeScript、Vite/Vitest bundle 和 Windows Codex sidecar 不允许硬编码依赖一定位于子 App 的 node_modules。解析必须兼容 npm 将依赖提升到根安装树,并在错误文案中统一要求从仓库根安装。
原生壳边界
- Mobile workspace 继续使用 Expo 默认 Metro 配置;当前不增加
node-linker或自定义watchFolders。首次迁移验收清理 Metro cache。 - Desktop H5 仍不得声明
@tauri-apps/api或任何@tauri-apps/plugin-*guest 依赖。 - AGC 可以在自己的 workspace manifest 声明 Tauri guest;统一根 lock 出现这些解析包是正常结果,不代表 Desktop 或根 H5 获得 guest 权限。
- 根 H5 manifest 也不得直接声明 Tauri guest。配置门禁按根、Desktop、AGC 三个 manifest 的所有权分别判断。
- Windows AGC release 必须从 workspace 或根提升位置找到
@openai/codex-win32-x64并把固定 sidecar 资源打包;Windows 构建 smoke 是迁移完成条件,不由 Linux lock 检查替代。
CI、Jenkins 与容器
- Gitea 四个 job 每个只执行一次带重试的根
npm ci,不再单独安装 AGC。 - Jenkins Web Build 必须在每个独立 shell 中加载
scripts/jenkins-prepare-npm-env.sh;该入口在 Jenkins 运行用户的版本隔离目录准备并优先使用 npm10.9.7,根 workspace 安装前再精确校验版本;RUN_NPM_CI只控制一次根npm ci。 - Gitea CI 镜像只维护一个 npm lock SHA 与一份 npm cache;预热上下文必须包含根 lock 和全部 workspace manifests,使根
npm ci能解析 workspace。 - CI 镜像仍分别维护 server-rs、Desktop Tauri、AGC Tauri 三份 Cargo lock cache;npm 单锁不改变 Rust lock 边界。
- API 镜像的 Web builder 必须显式安装并校验 npm
10.9.7,再复制全部 workspace manifests、执行根npm ci,之后才复制源码并构建主站与后台。 - 根 lock 或任一 workspace manifest 变化都需要刷新 CI 镜像 npm cache。缓存未命中只能报告
partial并受控补齐,不能跳过当前 lock 的干净安装。
验收
最低本地门禁:
npm ci
npm ls --workspaces --include-workspace-root --depth=0
npm run check:npm-workspaces
npm run typecheck
npm run test
npm run admin-web:typecheck
npm run preview-deployer:web:test
npm run mobile-shell:typecheck
npm run mobile-shell:test
npm run desktop-shell:typecheck
npm run ai-game-creator-shell:typecheck
npm run spine-export-validator:typecheck
npm run check:native-shells
npm run check:repository-ci
npm run check:production-ops
npm run check:encoding
git diff --check
干净安装验收必须在没有历史根或子 App node_modules 的隔离工作树执行。平台补充门禁:
- Linux:根、后台、预览部署器、Spine 工具构建,Desktop/AGC Tauri release smoke。
- Windows x64:根
npm ci后执行 AGC Tauri release smoke,核对 Codex sidecar 完整性。 - Android:Expo config/export,并在可用 EAS 环境执行一次本地 Android build。
- macOS/iOS:在可用 runner 执行 simulator build;缺少 runner 时必须标记未验证。
任何 workspace 仍需要第二次 npm ci --prefix、嵌套 lock、未声明直接依赖或依赖某个固定 node_modules 层级时,迁移都不能视为完成。