ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

airi 仓库 pnpm 迁移实战:从 npm/Yarn 到 pnpm,再到 v10→v11 配置迁移全解析

airi 仓库 pnpm 迁移实战:从 npm/Yarn 到 pnpm,再到 v10→v11 配置迁移全解析 airi 仓库 pnpm 迁移实战从 npm/Yarn 到 pnpm再到 v10→v11 配置迁移全解析【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi本篇基于 airi 仓库内置的迁移技能文档 best-practices-migration.md 展开系统讲解如何把现有 npm / Yarn 项目低摩擦地迁移到 pnpm以及如何完成 pnpm v10 → v11 的配置升级。读完本文你将掌握pnpm import锁文件导入、workspace 协议改造、v11 codemod 自动化迁移、.npmrc与pnpm-workspace.yaml配置拆分等完整操作并能以 airi 这个真实大型 monorepo 的 pnpm-workspace.yaml 和 package.json 作为落地参照。为什么 airi 是一个天然的 pnpm 迁移样本airi 是一个 LLM 驱动的虚拟角色项目self-hosted 的 Grok Companion支持实时语音聊天、Minecraft/Factorio 等玩法当前以 pnpm 作为唯一的包管理器根 package.json 中声明了packageManager: pnpm11.24.0即项目已运行在 pnpm v11 之上仓库根目录存在完整的 pnpm-workspace.yaml其中packages字段覆盖packages/**、plugins/**、integrations/**、services/**、docs/**、engines/**、apps/**、server/**八大目录并用!/dist/ 排除构建产物pnpm-lock.yaml 顶部即lockfileVersion: 9.0并在settings中记录了autoInstallPeers: true等安装行为。这意味着本文所有迁移步骤都能在 airi 中找到迁移完成后的目标形态读者可以对照仓库现状验证每一步的效果。一、pnpm v10 → v11配置读取方式的变化与 codemodv11 最大的变化在于配置从.npmrc/package.json#pnpm集中迁移到pnpm-workspace.yaml全局配置则放在config.yaml且键名统一为camelCase。这部分迁移大多是机械性的官方提供了 codemodcd /path/to/project pnpx codemod run pnpm-v10-to-v11codemod 会自动完成以下六类改写引自迁移文档的完整清单把package.json#pnpm设置移入pnpm-workspace.yaml——v11 不再读取pnpm字段拆分.npmrc只有 auth/registry 凭据留在.npmrc其余键全部以 camelCase 形式迁入pnpm-workspace.yaml例如node-linker→nodeLinker各子项目的.npmrc则变成packageConfigs[name]合并构建设置onlyBuiltDependencies、neverBuiltDependencies、ignoredBuiltDependencies、onlyBuiltDependenciesFile统一为一个allowBuilds: { name: true|false }映射替换包管理器版本管控managePackageManagerVersions/packageManagerStrict/packageManagerStrictVersion三个键合并为pmOnFail: download|ignore|warn|error重命名allowNonAppliedPatches→allowUnusedPatchesauditConfig.ignoreCves→auditConfig.ignoreGhsas转换useNodeVersion→devEngines.runtime并同步提升packageManager版本号。airi 中 v11 配置形态的真实例证airi 根目录的 pnpm-workspace.yaml 是上述迁移规则的直接产物几个关键键都可以逐条对上catalogMode: prefer minimumReleaseAge: 4320 minimumReleaseAgeExclude: - moeru/* - proj-airi/* shellEmulator: trueshellEmulator: true就是 v10 时代.npmrc中shell-emulatortrue的 camelCase 形态minimumReleaseAge/minimumReleaseAgeExclude属于 v11 的供应链安全配置限制依赖发布时间的下限并为本组织自有包豁免。再比如 pnpm-workspace.yaml 中的allowBuilds映射正是第 3 条构建设置合并的落地结果——airi 里有大量带原生编译步骤的依赖canvas、sharp、electron、node-pty、onnxruntime-node等每一个都被显式声明为true允许构建或false拒绝构建例如allowBuilds: canvas: true electron: true node-pty: true prisma/client: false better-sqlite3: false simple-git-hooks: false # [workworkaround] With shellEmulator: true, simple-git-hooks install may fail when no .git dir exists.可以看到 v11 的allowBuilds让哪些依赖允许执行 install 脚本变成了一份可 diff、可 review 的白名单这比 v10 时代分散在多个键里的onlyBuiltDependencies等配置清晰得多。无法自动化的手工跟进项codemod 覆盖不到的部分迁移文档列出了完整清单需逐一人工处理在auditConfig.ignoreGhsas中把CVE-…编号改写为GHSA-…格式ignorePatchFailures已被移除——失败的 patch 现在总是抛错airi 的 5 个补丁位于 patches/ 目录由 pnpm-workspace.yaml 的patchedDependencies引用迁移后任何一个补丁无法应用都会直接让安装失败环境变量npm_config_*→pnpm_config_*需检查 CI、shell profile、Docker 配置pnpm link name需改用路径形式pnpm link ./foopnpm link --global→pnpm add -g .无参数的pnpm install -g和pnpm server命令被移除名为clean/setup/deploy/rebuild的package.json脚本会遮蔽同名的 pnpm 内建命令需要显式调用内建时改用pnpm pm name。二、快速迁移从 npm / Yarn 切换从 npm 迁移# 删除 npm 锁文件与 node_modules rm -rf node_modules package-lock.json # 用 pnpm 重新安装 pnpm install从 Yarn 迁移# 删除 yarn 锁文件与 node_modules rm -rf node_modules yarn.lock # 用 pnpm 重新安装 pnpm install导入既有锁文件pnpm import不想从零解析依赖树时pnpm 支持直接消费旧锁文件# 从 npm 或 yarn 锁文件导入 pnpm import # 支持从以下文件生成 pnpm-lock.yaml # - package-lock.json (npm) # - yarn.lock (yarn) # - npm-shrinkwrap.json (npm)pnpm import的价值在于尽量保留 npm/yarn 时代已经锁定的版本解析结果降低迁移后行为漂移的风险airi 当前锁文件即为lockfileVersion: 9.0的 pnpm-lock.yaml其中还内嵌了 catalog 的 specifier→version 解析明细说明导入后的版本被完整固化。三、处理常见问题幽灵依赖Phantom Dependenciespnpm 默认采用严格依赖解析如果代码 import 了一个没有写进package.json的包安装/构建就会失败。问题示例// 在 npm提升式安装下能跑在 pnpm 下会失败 import lodash from lodash // 未声明只是被另一个包带进来的解决显式补齐依赖。pnpm add lodash这条规则解释了为什么许多从 npm 迁过来的项目一开始会莫名其妙报模块找不到——不是 pnpm 装丢了而是它第一次如实暴露了依赖声明缺失。缺失的 Peer Dependenciespnpm 默认会报告 peer dependency 问题有三种处理方式方式 1让 pnpm 自动安装v8 默认开启在pnpm-workspace.yaml中autoInstallPeers: trueairi 的锁文件设置区即启用了该行为pnpm-lock.yaml 的settings: autoInstallPeers: true。方式 2手动安装缺失的 peerpnpm add react react-dom方式 3在可接受的情况下抑制警告peerDependencyRules: ignoreMissing: - react对于 airi 这样多依赖树的大型 monorepo更常见的做法不是全局忽略而是用packageExtensions补齐上游漏声明的 peer。例如 pnpm-workspace.yaml 中为vitepress、formkit/auto-animate、pixiv/three-vrm-core等包补写了peerDependencies避免 peer 缺失报错同时不污染各子项目的package.json。符号链接兼容问题Symlink Issues个别工具无法正确跟随 pnpm 的 symlink 结构可以整体切换到 hoisted 模式nodeLinker: hoisted或者只把特定模式的包提升到node_modules顶层publicHoistPattern: - *eslint* - *babel*airi 当前未配置nodeLinker: hoisted即保持默认的 symlink 虚拟存储方案内容寻址 store 跨项目去重、磁盘占用最低只有当某个工具确实因 symlink 报错时再按上面的两个开关局部调整。原生模块重建Native Module Rebuilds原生模块构建失败时的标准处置# 重建所有原生模块 pnpm rebuild # 或者彻底重装 rm -rf node_modules pnpm install在 v11 项目里还要先确认目标包在allowBuilds中为true——airi 里uiohook-napi、stockfish、isolated-vm等都被显式放行pnpm-workspace.yaml这类构建审批机制就是原生模块问题的第一排查点。四、Monorepo 迁移从 npm Workspaces 迁移创建pnpm-workspace.yamlpackages: - packages/*内部依赖改用 workspace 协议{ dependencies: { myorg/utils: workspace:^ } }重新安装rm -rf node_modules packages/*/node_modules package-lock.json pnpm installairi 的实际情况可作为参照根 package.json 保留了workspaces字段packages/**、plugins/**等九个目录同时 pnpm-workspace.yaml 用 glob 列表描述了同一组目录并额外加了!**/dist/**排除项。从源码结构看pnpm 以pnpm-workspace.yaml为准package.json#workspaces属于兼容保留两者并存不会冲突但建议以 pnpm 侧为唯一事实来源维护。workspace 协议在子项目中的真实用法例如 packages/core-character/package.json 里的proj-airi/stream-kit: workspace:^apps/stage-web/package.json 则同时混用了workspace:与catalog:两种内部引用后者见下文配置迁移。从 Yarn Workspaces 迁移删除 Yarn 专属文件rm yarn.lock .yarnrc.yml rm -rf .yarn按package.json中的workspaces内容创建pnpm-workspace.yamlpackages: - packages/*视情况从package.json中移除 Yarn 的 workspace 配置可选pnpm 读取的是pnpm-workspace.yaml转换 workspace 引用// 来自 Yarn myorg/utils: * // 改为 pnpm myorg/utils: workspace:*从 Lerna 迁移对多数使用场景pnpm 原生能力可以替代 Lerna# Lerna在所有包中运行脚本 lerna run build # pnpm 等价写法 pnpm -r run build # Lerna在特定包中运行 lerna run build --scopemyorg/app # pnpm 等价写法 pnpm --filter myorg/app run build # Lerna发布 lerna publish # pnpm改用 changesets 流程 pnpm add -Dw changesets/cli pnpm changeset pnpm changeset version pnpm publish -rairi 的脚本层就是pnpm -rF/--filter用法的密集样本根 package.json 中dev: pnpm -r -F proj-airi/stage-web dev, dev:apps: pnpm -rF\./apps/*\ run --parallel dev, build: turbo run build -F\./packages/*\ -F\./apps/*\ -F\./server/**\-F--filter缩写既接受包名也接受路径 glob--parallel控制并行执行——这套组合完全覆盖了 Lernarun的日常能力而跨包的构建缓存与拓扑排序则交由turbo承担。五、配置迁移.npmrc与pnpm-workspace.yaml的职责划分v11 的核心原则.npmrc只保留 auth/registry 凭据其余全部迁入pnpm-workspace.yamlcamelCase。# .npmrc仅 auth建议 gitignore //registry.npmjs.org/:_authToken${NPM_TOKEN} //npm.myorg.com/:_authToken${MYORG_TOKEN}# pnpm-workspace.yaml registries: default: https://registry.npmjs.org/ myorg: https://npm.myorg.com/ autoInstallPeers: true strictPeerDependencies: false值得注意的是 airi 仓库根目录没有.npmrc文件——因为公开仓库没有任何需要入库的凭据这正是.npmrc只放 auth原则的极端形态无 auth 就无文件。在此之上airi 的 pnpm-workspace.yaml 还展示了 v11 配置面能承载的更重型的仓库级策略迁移时若旧项目有对应需求也应一并归位到这里overridesL25-L37强制统一版本与别名替换例如axios: npm:feaxios^0.0.23、hono: 4.13.3以及对is-core-module、side-channel等换成nolyfill/*的实现catalog/catalogsL44-L451集中版本目录子项目里直接写vue: catalog:、vitest: catalog:vitest多 catalog 命名空间配合catalogMode: prefer使用airi 根 package.json 的 devDependencies 几乎全部是catalog:引用patchedDependenciesL38-L43声明式补丁指向 patches/ 下的 5 个.patch文件mineflayer、pixi-live2d-display、uiohook-napi等替代 v10 时代package.json#pnpm.patchedDependencies的位置allowBuildsL455-L488前文所述的构建审批白名单。脚本迁移Scripts Migration多数脚本无需改动只需替换包管理器特定写法{ scripts: { // npm递归脚本 build:all: npm run build --workspaces, // pnpm改用 -r build:all: pnpm -r run build, // npm在指定 workspace 中运行 dev:app: npm run dev -w packages/app, // pnpm改用 --filter dev:app: pnpm --filter myorg/app run dev } }对照 airi 根 package.json 可看到这套模式的规模化应用dev:ui: pnpm -rF proj-airi/stage-ui run story:dev、typecheck: pnpm -rF\./packages/*\ ... --parallel typecheck等均按包名过滤 子脚本透传书写。六、CI/CD 迁移文档给出的通用改法是把npm ci换成 pnpm 的动作# Before (npm) - run: npm ci # After (pnpm) - uses: pnpm/action-setupv4 - run: pnpm install --frozen-lockfile # 或pnpm ci并在package.json中声明 Corepack 字段{ packageManager: pnpm10.0.0 }airi 主工作流 .github/workflows/ci.yml 展示的是等价的新式写法——用pnpm/setupv2一次性完成运行时 包管理器 缓存- uses: pnpm/setupv2 with: runtime: node26.7.0 cache: true install: false # ... - run: pnpm install --frozen-lockfile配合根 package.json 的packageManager: pnpm11.24.0CI 中的 pnpm 版本由 Corepack 机制从packageManager字段推导保证与本地一致--frozen-lockfile则确保锁文件不被 CI 静默改写。工作流中的构建步骤同样全部走pnpm -F pkg run build如pnpm -F proj-airi/stage-web run build与本地脚本形成闭环。七、渐进式迁移与回滚方案渐进式迁移Gradual Migration大型项目建议分步推进先切 CICI 用 pnpm本地暂留 npm/yarn生成 pnpm-lock.yaml跑pnpm import从旧锁文件导入充分测试确认构建、测试在 pnpm 下全部通过更新文档README、CONTRIBUTING 等统一为 pnpm 命令删除旧文件团队全员切换后移除旧锁文件。回滚计划Rollback Plan迁移出问题时# 删除 pnpm 产物 rm -rf node_modules pnpm-lock.yaml pnpm-workspace.yaml # 恢复 npm npm install # 或恢复 Yarn yarn install关键策略是把旧锁文件保留在 git 历史中以便随时 checkout 回来把回滚成本压到最低。八、小结迁移检查清单把全文压缩成一份可执行的核对表步骤关键操作airi 中的对应证据v10→v11 codemodpnpx codemod run pnpm-v10-to-v11pnpm-workspace.yaml 的 camelCase 键与allowBuilds锁文件切换pnpm import/ 删除旧锁文件重装pnpm-lock.yamllockfileVersion: 9.0幽灵依赖显式pnpm add补齐声明严格模式默认行为peer 依赖autoInstallPeers/peerDependencyRules/packageExtensions锁文件 settings、pnpm-workspace.yamlMonorepopnpm-workspace.yamlworkspace:协议package.json、packages/core-character/package.json配置拆分.npmrc只留 auth其余入pnpm-workspace.yaml仓库根目录无.npmrcCIpnpm/setuppnpm install --frozen-lockfilepackageManager字段.github/workflows/ci.yml、package.json这套迁移路径在 airi 上已完整落地从packageManager声明、pnpm-workspace.yaml的八大工作区 glob到allowBuilds构建审批与 5 个声明式补丁都可以作为迁移完成后应当达到的配置形态来参照。【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表