shamefully-hoist 是 pnpm 的一个配置选项,用于创建类似 npm/Yarn 的扁平化 node_modules 结构。
默认行为 vs shamefully-hoist:
bash# 默认 pnpm 结构(严格) node_modules/ ├── .pnpm/ │ └── lodash@4.17.21/ └── lodash -> .pnpm/lodash@4.17.21/node_modules/lodash # 只能访问声明的依赖 const lodash = require('lodash'); // ✅ 正常 const debug = require('debug'); // ❌ 错误(未声明)
bash# shamefully-hoist=true 结构(扁平化) node_modules/ ├── .pnpm/ ├── lodash/ ├── debug/ # 被提升上来 └── ... # 可以访问所有依赖 const lodash = require('lodash'); // ✅ 正常 const debug = require('debug'); // ✅ 可以访问(幽灵依赖)
配置方法:
ini# .npmrc shamefully-hoist=true # 或只提升特定包 shamefully-hoist-pattern[]=webpack shamefully-hoist-pattern[]=*types*
使用场景:
- 遗留项目迁移
ini# 项目依赖幽灵依赖,暂时无法修改 # .npmrc shamefully-hoist=true # 迁移完成后应关闭 # shamefully-hoist=false
- 特定工具兼容
ini# 某些工具需要扁平化结构 # 如某些 webpack 插件、IDE 等 shamefully-hoist=true
- 混合使用
ini# 只提升特定包 public-hoist-pattern[]=*eslint* public-hoist-pattern[]=*prettier* public-hoist-pattern[]=*types*
相关配置对比:
| 配置 | 作用 | 推荐度 |
|---|---|---|
shamefully-hoist | 完全扁平化 | ⭐⭐ |
public-hoist-pattern | 部分扁平化 | ⭐⭐⭐⭐⭐ |
hoist-pattern | 内部扁平化 | ⭐⭐⭐⭐ |
public-hoist-pattern 推荐配置:
ini# .npmrc # 提升类型定义包 public-hoist-pattern[]=*types* # 提升构建工具 public-hoist-pattern[]=*eslint* public-hoist-pattern[]=*prettier* public-hoist-pattern[]=*webpack* # 提升测试工具 public-hoist-pattern[]=*jest* public-hoist-pattern[]=*vitest*
为什么不推荐完全扁平化:
javascript// shamefully-hoist=true 的问题 // 1. 幽灵依赖 const someDep = require('some-dep'); // 实际未在 package.json 中声明 // 可能导致 CI/CD 失败 // 2. 版本冲突 // 不同包依赖同一包的不同版本 // 扁平化后只能有一个版本 // 3. 失去 pnpm 的优势 // 磁盘空间节省减少 // 依赖管理不严格
最佳实践:
ini# 推荐配置 # .npmrc # 默认不扁平化 shamefully-hoist=false # 只提升必要的包 public-hoist-pattern[]=*eslint* public-hoist-pattern[]=*prettier* public-hoist-pattern[]=*types* # 严格模式 strict-peer-dependencies=true
迁移策略:
bash# 1. 先启用 shamefully-hoist 迁移 # .npmrc shamefully-hoist=true # 2. 运行项目,检查是否有问题 pnpm install pnpm build pnpm test # 3. 逐步修复幽灵依赖 # 找到所有未声明的依赖 pnpm ls --depth=10 # 4. 添加到 package.json pnpm add missing-dep # 5. 关闭 shamefully-hoist # .npmrc shamefully-hoist=false
检查幽灵依赖:
bash# 使用 depcheck 检查 cd project npx depcheck # 或使用 pnpm 检查 pnpm ls --depth=0
总结:
shamefully-hoist是迁移过渡方案- 长期使用应关闭,保持 pnpm 的严格性
- 使用
public-hoist-pattern替代完全扁平化 - 逐步修复幽灵依赖,回归标准模式