乐闻世界logo
搜索文章和话题

What is pnpm's shamefully-hoist configuration and when should it be used?

3月7日 12:16

shamefully-hoist is a pnpm configuration option used to create a flat node_modules structure similar to npm/Yarn.

Default Behavior vs shamefully-hoist:

bash
# Default pnpm structure (strict) node_modules/ ├── .pnpm/ │ └── lodash@4.17.21/ └── lodash -> .pnpm/lodash@4.17.21/node_modules/lodash # Can only access declared dependencies const lodash = require('lodash'); // ✅ Normal const debug = require('debug'); // ❌ Error (not declared)
bash
# shamefully-hoist=true structure (flat) node_modules/ ├── .pnpm/ ├── lodash/ ├── debug/ # Hoisted up └── ... # Can access all dependencies const lodash = require('lodash'); // ✅ Normal const debug = require('debug'); // ✅ Accessible (phantom dependency)

Configuration Method:

ini
# .npmrc shamefully-hoist=true # Or hoist only specific packages shamefully-hoist-pattern[]=webpack shamefully-hoist-pattern[]=*types*

Usage Scenarios:

  1. Legacy Project Migration
ini
# Project depends on phantom dependencies, temporarily can't modify # .npmrc shamefully-hoist=true # Should disable after migration # shamefully-hoist=false
  1. Specific Tool Compatibility
ini
# Some tools require flat structure # Such as certain webpack plugins, IDEs, etc. shamefully-hoist=true
  1. Mixed Usage
ini
# Only hoist specific packages public-hoist-pattern[]=*eslint* public-hoist-pattern[]=*prettier* public-hoist-pattern[]=*types*

Configuration Comparison:

ConfigurationEffectRecommendation
shamefully-hoistFully flat⭐⭐
public-hoist-patternPartially flat⭐⭐⭐⭐⭐
hoist-patternInternal flat⭐⭐⭐⭐

public-hoist-pattern Recommended Configuration:

ini
# .npmrc # Hoist type definition packages public-hoist-pattern[]=*types* # Hoist build tools public-hoist-pattern[]=*eslint* public-hoist-pattern[]=*prettier* public-hoist-pattern[]=*webpack* # Hoist test tools public-hoist-pattern[]=*jest* public-hoist-pattern[]=*vitest*

Why Not Recommend Full Flattening:

javascript
// Problems with shamefully-hoist=true // 1. Phantom dependencies const someDep = require('some-dep'); // Actually not declared in package.json // May cause CI/CD failures // 2. Version conflicts // Different packages depend on different versions of same package // After flattening, only one version can exist // 3. Lose pnpm advantages // Reduced disk space savings # Less strict dependency management

Best Practices:

ini
# Recommended configuration # .npmrc # Default no flattening shamefully-hoist=false # Only hoist necessary packages public-hoist-pattern[]=*eslint* public-hoist-pattern[]=*prettier* public-hoist-pattern[]=*types* # Strict mode strict-peer-dependencies=true

Migration Strategy:

bash
# 1. First enable shamefully-hoist for migration # .npmrc shamefully-hoist=true # 2. Run project, check for issues pnpm install pnpm build pnpm test # 3. Gradually fix phantom dependencies # Find all undeclared dependencies pnpm ls --depth=10 # 4. Add to package.json pnpm add missing-dep # 5. Disable shamefully-hoist # .npmrc shamefully-hoist=false

Check Phantom Dependencies:

bash
# Use depcheck to check cd project npx depcheck # Or use pnpm to check pnpm ls --depth=0

Summary:

  • shamefully-hoist is a migration transition solution
  • Should be disabled for long-term use to maintain pnpm's strictness
  • Use public-hoist-pattern instead of full flattening
  • Gradually fix phantom dependencies and return to standard mode
标签:PNPM