Phantom dependencies in strict mode复制
pnpm 默认的严格 node_modules 布局要求包只能导入自己 package.json 里明确声明的依赖。导入未声明的传递依赖会在运行时报 MODULE_NOT_FOUND 错误。
⚠ 常见坑: 如果 `import "some-package"` 在 npm 项目里能用但在 pnpm 里失败,那就是幽灵依赖。修法是把 `some-package` 加到对应包的 devDependencies 里。不要用 shamefully-hoist 掩盖问题。
例子 # To find which package actually owns some-package:
pnpm why some-package --filter @myapp/web Lockfile version conflict on pnpm upgrade复制
pnpm 锁文件格式在大版本之间会变。升级 pnpm 后,先跑 `pnpm install` 用新格式重新生成锁文件再提交。
⚠ 常见坑: 升级 pnpm 后提交旧格式的锁文件,会导致每个团队成员(和 CI)在重新生成锁文件之前都遇到 "ERR_PNPM_LOCKFILE_MISSING_DEPENDENCY" 或格式不匹配的报错。
例子 # After upgrading pnpm:
pnpm install
git add pnpm-lock.yaml
git commit -m "chore: regenerate lockfile for pnpm vX" Package not found after rename复制
重命名 workspace 包(修改其 package.json 里的 `name`)后,如果没有同步更新兄弟包里的 `workspace:` 引用,安装就会报错。
⚠ 常见坑: pnpm install 会报 "No matching version found for @old/name",因为 workspace 协议按名字而不是目录路径查找包。
例子 # After renaming @myapp/foo to @myapp/bar:
# 1. Update all "workspace:*" refs from @myapp/foo → @myapp/bar
# 2. pnpm install
# grep to find all stale references:
grep -r "@myapp/foo" packages/ apps/ peer dependency warnings in workspace复制
pnpm 比 npm 更积极地报 peer 依赖问题。`WARN … peer dependencies unmet` 消息可能不会中断构建,但可能说明真实的兼容性问题。
⚠ 常见坑: 在 .npmrc 里设 `strict-peer-dependencies=false` 能关掉警告但不解决根本问题。关掉之前先排查一下。
例子 # To silence peer dep warnings globally (use sparingly):
# .npmrc
strict-peer-dependencies=false # To see what peer deps are unmet:
pnpm ls --depth 1 --filter @myapp/web "workspace:*" in publishable package复制
在要发布到 npm 的包里用 `workspace:*`,消费者拿到的是 `"dep": "1.2.3"`(精确锁定)。他们无法自动拿到 patch 更新——改用 `workspace:^`。
例子 # Wrong for published libs:
"@myapp/utils": "workspace:*"
# Right for published libs:
"@myapp/utils": "workspace:^" pnpm run at wrong cwd复制
在 workspace 根目录跑 `pnpm run dev` 本意是跑某个子包的 dev,结果跑的是根目录的 dev 脚本(往往没有定义)。
⚠ 常见坑: 如果根目录没有 `dev` 脚本,会报 "ERR_PNPM_NO_SCRIPT"。要么加 `--filter`,要么先 cd 进包目录。
例子 # Always use --filter from root:
pnpm run --filter @myapp/web dev
# Or cd first:
cd apps/web && pnpm run dev Missing --frozen-lockfile in CI复制
CI 里跑普通 `pnpm install` 允许 pnpm 在 package.json 有偏差时静默更新锁文件。自动化流水线里始终要用 `pnpm install --frozen-lockfile` 或 `pnpm ci`。
例子 # .github/workflows/ci.yml
- run: pnpm install --frozen-lockfile # equivalent shorthand:
- run: pnpm ci pnpm catalog: on pnpm < 9复制
pnpm < 9 里 package.json 里的 `catalog:` 说明符会被静默当成未知版本——包要么没有版本约束地安装,要么直接安装失败。
⚠ 常见坑: 采用 catalog: 之前先检查 `pnpm --version`。如果团队或 CI 的 pnpm 版本不统一,在根 package.json 的 `engines.pnpm` 字段里强制最低版本。
例子 # root package.json
"engines": {
"pnpm": ">=9.0.0"
} # Also add to .npmrc:
engine-strict=true Turborepo cache stale after dep change复制
如果配合 Turborepo 使用 pnpm workspace,重命名包或修改 workspace: 引用会让 turbo 的依赖图哈希失效。结构性修改后跑 `turbo run build --force` 强制清缓存。
例子 turbo run build --force # Or delete the .turbo directory:
rm -rf .turbo && turbo run build