ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

AIRI 单仓的 pnpm 实践手册:从 pnpm-workspace.yaml 配置模型到 Catalogs、Patches 与供应链安全

AIRI 单仓的 pnpm 实践手册:从 pnpm-workspace.yaml 配置模型到 Catalogs、Patches 与供应链安全 AIRI 单仓的 pnpm 实践手册从 pnpm-workspace.yaml 配置模型到 Catalogs、Patches 与供应链安全【免费下载链接】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 仓库中的技能文档 .agents/skills/pnpm/SKILL.md 为主体系统讲解 pnpm以 10.x/11.x 为基准的命令体系、配置模型与高级特性并结合 AIRI 自身的 pnpm-workspace.yaml、package.json 与 patches/ 目录展示这套方案在一个真实大型 Vue/TS 单仓monorepo中的落地形态。读完后你将能够独立配置 pnpm 工作区、用 Catalogs 统一版本、管理第三方补丁并理解 pnpm 11 的供应链安全机制如何保障安装过程的可信性。1. 文档定位一份面向 Agent 的 pnpm 技能地图SKILL.md 的 frontmatter 说明了它的用途当需要在 pnpm 项目中执行 pnpm 命令、配置pnpm-workspace.yaml工作区或管理 catalogs、patches、overrides、config dependencies 与全局 virtual store 时使用该技能。文档基于 pnpm 10.x 生成生成日期 2026-06-22作者 Anthony Fu同时覆盖 v11 的行为变更配置拆分、隔离式全局包、allowBuilds、pmOnFail与全局 virtual store。技能文档把 pnpm 知识组织为四大板块每块都指向一份参考文档板块覆盖内容参考文档CoreCLI 命令、配置模型、工作区、内容寻址存储core-cli、core-config、core-workspaces、core-storeFeaturesCatalogs、Overrides、Patches、Aliases、Hooks、Peer Dependencies、Config Dependencies、全局虚拟仓库、供应链安全features-catalogs、features-patches、features-supply-chain-security 等Best PracticesCI/CD 搭建、从 npm/Yarn 迁移、性能优化best-practices-ci、best-practices-migration、best-practices-performanceAIRI 根目录 package.json 中packageManager: pnpm11.24.0表明仓库实际运行在 pnpm 11 上因此下文的 v11 行为尤其是配置拆分与构建脚本审批是该仓库的真实约束条件。2. 配置模型pnpm-workspace.yaml 是唯一主配置技能文档开篇就强调了当前 pnpm 最重要的配置概念——配置两分法类别存放位置格式所有 pnpm/安装设置nodeLinker、hoistPattern、autoInstallPeers、overrides、catalog等pnpm-workspace.yaml项目级与全局config.yamlYAMLcamelCase键名认证与仓库凭据_authToken、cert、key等项目.npmrcgitignore与全局rc文件INI三条关键变化见 core-configpackage.json的pnpm字段不再被读取——所有设置移入pnpm-workspace.yaml.npmrc仅用于认证/仓库凭据其余配置含以前写在.npmrc的 kebab-case 项一律进 YAML且键名改为 camelCasenpm_config_*环境变量不再被读取改用pnpm_config_*或PNPM_CONFIG_*例如pnpm_config_save_exacttrue pnpm add foo。工作区内的按包配置也不再使用子项目.npmrc而是通过根目录的packageConfigs# pnpm-workspace.yaml packageConfigs: project-1: saveExact: true project-2: savePrefix: ~旧的构建脚本审批配置onlyBuiltDependencies、neverBuiltDependencies等统一收敛为一个allowBuilds映射包管理器严格性收敛为pmOnFail: download | ignore | warn | error运行时固定改用package.json的devEngines.runtime。AIRI 的真实配置逐段拆解AIRI 的 pnpm-workspace.yaml 是该配置模型的完整实例下面逐段对照工作区成员packages——覆盖全部九个顶层目录并显式排除构建产物packages: - packages/** - plugins/** - integrations/** - services/** - examples/** - docs/** - engines/** - apps/** - server/** - !**/dist/**根 package.json 中还保留了一个workspaces数组内容与上述 glob 一致这是给 npm 生态工具看的冗余声明pnpm 本身只认pnpm-workspace.yaml。Catalog 行为与供应链参数catalogMode: prefer # pnpm add 时优先使用默认 catalog 中的版本 minimumReleaseAge: 4320 # 发布 72 小时内的新版本默认不安装默认值 1440 分钟/1 天 minimumReleaseAgeExclude: # 项目自有 scope 豁免允许即时安装 - moeru/* - proj-airi/* - vishot/* - xsai/* # ... 等 shellEmulator: true # 用 Node 模拟 shell 执行生命周期脚本规避 Windows/沙箱问题minimumReleaseAge的取值4320分钟3 天高于 v11 默认值14401 天说明 AIRI 对新发布的依赖采取了更保守的窗口minimumReleaseAgeExclude精确豁免了项目自有 scopeproj-airi、moeru等保证内部包的迭代不受发布年龄限制。Overrides强制版本与 npm 别名。这是 AIRI 依赖治理的核心手段之一overrides: types/hast: catalog: # 覆盖为 catalog 版本版本只在一处维护 array-flatten: npm:nolyfill/array-flatten^1.0.44 # 用 npm: 别名替换为 nolyfill 版本 axios: npm:feaxios^0.0.23 # 全局替换 axios 为兼容封装 feaxios eslint-plugin-sonarjstypescript: catalog: # 仅针对传递依赖路径定向覆盖 hono: 4.13.3 # 精确锁定 onnxruntime-web: npm:onnxruntime-web^1.27.0 # 其余为若干 nolyfill/* 替换isarray、safe-buffer、side-channel 等这里体现了技能文档中两类特性npm:包别名features-aliases用于在不改依赖方代码的前提下整体替换实现axios → feaxios、node-pty → lydell/node-pty亦见于 catalog 定义以及catalog:协议在overrides中的合法性——让被覆盖项与默认 catalog 保持同一版本来源。packageExtensions修补有缺陷的包清单。当上游包没有正确声明 peer/optional 依赖时用packageExtensions在本地“扩展”其 manifestpackageExtensions: formkit/auto-animate: peerDependencies: vue: * pixiv/three-vrm-core: peerDependencies: types/three: * vitepress: peerDependencies: vite: * vue: * # ... 共 11 处扩展这避免了pnpm peers check见 core-cli报出缺失 peer 告警也无需peerDependencyRules.ignoreMissing粗暴忽略。3. Catalogs单仓版本治理的“单一事实来源”features-catalogs 定义了 Catalogs 的完整语义在pnpm-workspace.yaml中定义版本各包package.json中以catalog:引用。默认 catalog 写在catalog:键下catalog:是catalog:default的简写命名 catalog 写在catalogs:键下引用语法为catalog:namecatalog:协议可用于dependencies/devDependencies/peerDependencies/optionalDependencies也可用于pnpm-workspace.yaml的overrides甚至 CLIpnpm add reactcatalog:、pnx shxcatalog:行为由catalogMode控制v10.12manual默认不自动纳入、preferpnpm add时若版本匹配则写入catalog:、strict只允许 catalog 版本发布时catalog:会被替换为真实版本如catalog:→^18.2.0对外发布透明。AIRI 的 catalog 规模AIRI 的默认 catalog 收录了400 余项依赖pnpm-workspace.yaml 第 44 行起覆盖 Vue 全家桶vue ^3.5.41、pinia ^4.0.3、vue-router ^5.2.0、Three.js 生态three ^0.185.1、pixiv/three-vrm ^3.5.5、Electron 工具链electron ^43.4.1、electron-builder ^26.15.3、语音管线kokoro-js、onnxruntime-web、huggingface/transformers、以及 Minecraft 集成mineflayer ^4.37.1及全套 prismarine 包。同时定义了两个命名 catalogcatalogs: vitest: vitest/browser-playwright: ^4.1.11 vitest/coverage-v8: ^4.1.11 vitest: ^4.1.11 xsai: unspeech: ^0.1.16根 package.json 正是消费方devDependencies 中vitest: catalog:vitest、vitest/browser-playwright: catalog:vitest其余工具链依赖统一catalog:。配合catalogMode: prefer日后pnpm add时会自动倾向写入 catalog 引用而非散落的版本字面量——升级依赖只需改一处且各包package.json基本不动显著减少合并冲突。这正是参考文档列出的四大收益单一事实来源、全仓一致、一处升级、更少冲突。文档还给出了一条从 overrides 迁移到 catalogs 的自动化命令pnpx codemod pnpm/catalog。4. 核心命令体系安装、脚本、过滤与补丁以下命令清单完整继承自 core-cli并结合 AIRI 根package.json中实际脚本pnpm -rF proj-airi/stage-web dev、turbo run build -F...、taze -w -r -I pnpm prune pnpm dedupe给出验证。安装类pnpm install # 安装全部依赖别名 pnpm i pnpm add pkg [-D|-O|-E] # dev/optional/精确版本 pnpm remove pkg # 别名 rm / uninstall / un pnpm update [--latest|-i] pnpm install --frozen-lockfile # lockfile 将被修改时直接失败CI 中自动启用 pnpm ci # pnpm clean install --frozen-lockfile pnpm clean [--lockfile] # 清理全工作区 node_modules别名 purgev11 注意tarball 与 lockfile 校验和不匹配是硬错误ERR_PNPM_TARBALL_INTEGRITY需人工核验新字节后才可pnpm install --update-checksumsCI 中由更新大版本 pnpm 写出的 lockfile 也会直接失败。脚本执行pnpm run script # 或简写 pnpm script pnpm run build -- --watch # -- 之后的参数透传 pnpm run --if-present build pnpm exec cmd # 执行本地二进制如 pnpm exec eslint .隐藏脚本.开头不可直接执行与内置命令同名的脚本clean、setup、deploy、rebuild优先执行package.json脚本强制用内置命令时写作pnpm pm clean。一次性运行无需安装的工具pnx create-vite my-app # pnx pnpm dlx pnpx支持 catalog: 协议 pnx --packagescope/tool tool --helpv11 中dlx/pnx默认使用全局 virtual store并遵守minimumReleaseAge、trustPolicy等供应链设置。工作区过滤AIRI 日常脚本的骨架pnpm -r run script # 所有包含该脚本的包--recursive pnpm --filter pattern run script # -F 简写 pnpm --filter ./packages/** run build # glob 目录 pnpm --filter myorg/* run lint # 名称前缀 pnpm -r --parallel run dev # 并行 pnpm --filter ...scope/app build # 包及其依赖 pnpm --filter scope/core... test # 包及其依赖者 pnpm --filter ...[origin/main] build # 相对某 git ref 有变更的包AIRI 根脚本大量使用这种组合例如dev:apps: pnpm -rF\./apps/*\ run --parallel dev、typecheck: pnpm -rF\./packages/*\ -F\./apps/*\ -F\./server/**\ -F\./docs\ --parallel typecheck。工作区级安装/发布命令pnpm --filter myorg/app add lodash # 向指定包添加依赖 pnpm publish -r --no-git-checks # CI 发布跳过 git 工作树检查发布时workspace:协议按变体转换为真实版本workspace:*→ 实际版本workspace:^→^x.y.zworkspace:~→~x.y.z见 core-workspaces。补丁Patches修改第三方包并固化到仓库features-patches 定义的三步流程pnpm patch pkgversion # 1. 生成可编辑副本并输出临时路径 # 2. 在临时目录中修改源码 pnpm patch-commit path # 3. 生成 patches/pkg.patch 并写入配置 pnpm patch-remove pkgversion提交后配置记录在pnpm-workspace.yaml的patchedDependencies不再是package.json#pnpm。不带版本号的键express:会补丁所有已安装版本v11 移除了ignorePatchFailures补丁应用失败必定抛错可用allowUnusedPatches: true容忍“已声明但未应用”的补丁。AIRI 的 5 个真实补丁pnpm-workspace.yaml 第 38-43 行patchedDependencies: mineflayer-pathfinder: patches/mineflayer-pathfinder.patch pixi-live2d-display: patches/pixi-live2d-display.patch sponsorkit17.1.0: patches/sponsorkit17.1.0.patch tab-election4.6.2: patches/tab-election4.6.2.patch uiohook-napi1.5.5: patches/uiohook-napi1.5.5.patch可以看到两种键名风格的混用mineflayer-pathfinder与pixi-live2d-display不带版本号补丁所有版本而sponsorkit17.1.0、uiohook-napi1.5.5等精确锁定版本。补丁文件本体就在仓库 patches/ 目录下如 patches/sponsorkit17.1.0.patch全部以 unified diff 格式提交入库任何开发者pnpm install后即自动获得一致的第三方行为——这正是补丁“可复现、可审查”的要点。5. 供应链安全v11 默认拦截的攻击面features-supply-chain-security 描述了 pnpm 默认拦截的几类攻击向量AIRI 的配置全部落在这一框架内构建脚本审批allowBuilds默认情况下 pnpm不执行任何依赖的生命周期脚本preinstall/install/postinstall必须显式审批。审批集中在一个allowBuilds映射替换了被移除的onlyBuiltDependencies等五个旧配置allowBuilds: esbuild: true core-js: false nx21.6.4 || 21.6.5: true # 支持版本选择器未列出的包视为“未审查”默认被拦截strictDepBuilds默认true使未审查构建导致安装非零退出ERR_PNPM_IGNORED_BUILDS。审批命令pnpm approve-builds # 交互式 pnpm approve-builds --all # 全批 pnpm approve-builds esbuild fsevents !core-js # ! 表示拒绝 pnpm add --allow-buildesbuild my-bundler # 添加时顺带审批AIRI 的 pnpm-workspace.yaml 第 455-488 行给出了一个 30 条目的审批清单electron、esbuild、sharp、canvas、ffmpeg-static等为true这些包的 postinstall 下载/编译二进制资源是必需的ax-llm/ax、prisma/client、better-sqlite3为false最典型的一条simple-git-hooks: false # [workaround] With shellEmulator: true, simple-git-hooks install may fail when no .git dir exists.注释直接解释了拒绝原因——在shellEmulator: true下无.git目录时该脚本会失败这是审批机制与根脚本postinstall: pnpm exec simple-git-hooks ...改用 exec 手动触发配合工作的结果。文档同时警告逃生舱dangerouslyAllowAllBuilds: true会放行一切构建脚本应避免使用。最小发布年龄、信任策略与来源封锁minimumReleaseAge: 4320 # 分钟v11 默认 14401 天 minimumReleaseAgeExclude: [...] # 豁免列表 trustPolicy: no-downgrade # 包信任级别降级如失去 provenance即失败 blockExoticSubdeps: true # 默认仅直接依赖可用 git/直连 tarball 等“奇特来源”minimumReleaseAge覆盖全部依赖含传递依赖恶意发布通常在一小时内被下架延迟窗口能有效规避minimumReleaseAgeStrict控制“无满足年龄的版本时”是失败还是回退旧版。Lockfile 完整性自 v11 起下载 tarball 的哈希与pnpm-lock.yaml不一致即为硬错误ERR_PNPM_TARBALL_INTEGRITY--force与pnpm update均不能绕过——这是保护已提交 lockfile 不被投毒注册表/代理篡改的最后一道防线。内容寻址 store、全局 virtual store 与元数据缓存都属于 pnpm 的信任域只应在相互信任的机器/任务间共享。6. Store、Node Linker 与全局虚拟仓库core-store 说明了 pnpm 的存储原理所有包按内容哈希存入全局内容寻址 store项目node_modules通过硬链接/符号链接引用同一版本跨项目只存一份。核心命令与布局pnpm store path # 查看 store 位置 pnpm store prune # GC 无引用包含全局 virtual store 链接 pnpm store status # 校验完整性 pnpm store add pkgproject/ └── node_modules/ ├── .pnpm/ # 虚拟仓库硬链接到全局 store │ └── lodash4.17.21/node_modules/lodash/ ├── lodash - .pnpm/lodash4.17.21/node_modules/lodash └── express - .pnpm/express4.18.2/node_modules/expressnodeLinker三模式pnpm-workspace.yaml中设置isolated默认符号链接虚拟仓库严格依赖解析、无幽灵依赖——AIRI 采用默认值hoistednpm 式扁平node_modules供不支持符号链接的工具兼容pnp无node_modules需另设symlink: false。网络盘/Docker 等硬链接失效场景可用packageImportMethod: copy默认auto按 clone → hardlink → copy 顺序尝试。v11.7 的frozenStore: true允许对只读 storeNix store、只读挂载、OCI 层执行pnpm install --frozen-store --offline --frozen-lockfile。全局虚拟仓库features-global-virtual-storeenableGlobalVirtualStore: true时项目不再各自维护node_modules/.pnpm其node_modules只是指向store-path/links/中按依赖图哈希共享目录的符号链接。v11 中它已是pnpm dlx/全局安装的默认项目安装仍为 opt-in特别适合 git worktree 多 Agent 并行开发场景。7. CI/CD冻结 lockfile、store 缓存与镜像构建best-practices-ci 的要点CI 环境下 pnpm 自动进入 frozen-lockfile 模式v11 起对“由更新大版本写入的 lockfile”直接失败不回写因此 CI 的 pnpm 大版本需与 lockfile 生成者保持一致。GitHub Actions 标准写法- uses: pnpm/action-setupv4 with: run_install: false - name: Get pnpm store directory shell: bash run: echo STORE_PATH$(pnpm store path --silent) $GITHUB_ENV - uses: actions/cachev4 with: path: ${{ env.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles(**/pnpm-lock.yaml) }} restore-keys: | ${{ runner.os }}-pnpm-store- - run: pnpm install --frozen-lockfileDocker 多阶段构建中v11 的全局 bin 位于$PNPM_HOME/bin需ENV PATH$PNPM_HOME/bin:$PATH官方镜像ghcr.io/pnpm/pnpm:version可搭配pnpm runtime set node ver -g自行管理 Node。单仓只构建变更包的策略pnpm --filter ...[origin/main] build。版本固定通过 package.json 的packageManager: pnpm11.24.0Corepack 消费完成范围式固定用devEngines.packageManager解析版本存于 lockfile外部版本管理器asdf/mise/Volta场景可设pmOnFail: ignore。另外从仓库结构看AIRI 还有 flake.nix 与 nix/pnpm-deps-hash.txt配套 nix/update-pnpm-deps-hash.sh推测用于 Nix 构建链中固定 pnpm 依赖树与上文 frozen store / frozen lockfile 的复现思路一脉相承由于未逐行核对该 Nix 实现此处不作进一步断言。8. 关键要点速查配置三分所有 pnpm 设置进pnpm-workspace.yamlcamelCase.npmrc只管认证package.json#pnpm与npm_config_*已废弃。Catalogs 是单仓版本治理主入口AIRI 用 400 条默认 catalog 2 个命名 catalogvitest、xsaicatalogMode: prefer实现“一处改版本、全仓生效、package.json 零冲突”。Overrides 与 npm: 别名做依赖替换axios → feaxios、多包nolyfill/*替换、传递依赖路径定向覆盖pkga: catalog:。补丁入库即复现patchedDependenciespatches/*.patch使第三方修复对所有人确定生效v11 中补丁失败必抛错。v11 安全默认allowBuilds白名单AIRI 30 条审批、minimumReleaseAge: 4320、lockfile 完整性硬校验、blockExoticSubdeps。CI 三件套pnpm ci/--frozen-lockfile、按 lockfile 哈希缓存 store、packageManager精确固定大版本。存储即信任域store、全局 virtual store、元数据缓存只在与受信环境间共享硬链接不可用时回退packageImportMethod: copy。对照 .agents/skills/pnpm/SKILL.md 的三板块表格本文已覆盖 CoreCLI/配置/工作区/Store、FeaturesCatalogs/Overrides/Patches/供应链安全与 Best PracticesCI/CD中与 AIRI 实际配置强相关的部分其余参考文档Aliases、Hooks、Peer Dependencies、Config Dependencies、Migration、Performance 等可按表格中的仓库相对路径继续深入。【免费下载链接】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),仅供参考
返回列表