阿里云主机折上折
  • 微信号
Current Site:Index > Mixing package managers (npm + yarn + pnpm randomly used)

Mixing package managers (npm + yarn + pnpm randomly used)

Author:Chuan Chen 阅读数:54455人阅读 分类: 前端综合

Package Manager Mixing Strategy

Using npm, yarn, and pnpm simultaneously in a frontend project is like using three different brands of kitchen knives to chop ingredients—each with varying sharpness and handle ergonomics, resulting in wildly uneven cuts. The three lock files—package-lock.json, yarn.lock, and pnpm-lock.yaml—coexist happily in the project root, like three incompatible roommates sharing the same fridge.

# Typical project directory structure
project-root/
├── node_modules/          # A black hole of a directory
├── package.json           # The root of all chaos
├── package-lock.json      # npm's pride
├── yarn.lock              # A graceful taunt
└── pnpm-lock.yaml         # The new challenger

Dependency Installation Russian Roulette

Every installation command is a thrilling adventure, with team members never knowing what shape node_modules will take next. Turning CI/CD pipelines into a lottery draw:

// package.json snippet
{
  "scripts": {
    "install:random": "if ((RANDOM % 3 == 0)); then npm install; elif ((RANDOM % 2 == 0)); then yarn; else pnpm i; fi",
    "postinstall": "rm -rf node_modules && echo 'Please try again'"
  }
}

Version Conflict Carnival

The differing dependency resolution strategies of package managers create breathtaking version conflict art. For example, when webpack is 4.x under npm, 5.x under yarn, and pnpm stubbornly sticks to 3.x:

# Comparison of running in three terminals
$ npm list webpack
└── webpack@4.46.0

$ yarn why webpack
=> Found "webpack@5.76.0"

$ pnpm why webpack
webpack@3.12.0

Script Execution Chaos Theory

The behavior of preinstall/postinstall scripts across managers is like Schrödinger's cat—you never know if they'll fail until you run them:

{
  "scripts": {
    "preinstall": "echo 'This script might run twice under yarn'",
    "postinstall": "rm -rf $(whoami == 'root' ? '/etc' : 'dist')"
  }
}

Cache System Trio

The caching mechanisms of the three package managers wage an endless war on disk space:

# Check cache usage
$ du -sh ~/.npm ~/.yarn ~/.pnpm-store
4.2G    /Users/me/.npm
3.7G    /Users/me/.yarn
5.1G    /Users/me/.pnpm-store

Dependency Hoisting Quantum State

The structure of node_modules takes entirely different topological forms under different managers, turning require.resolve into a probability function:

// This path could exist anywhere
const path = require.resolve('lodash');
console.log(path);
// npm:  /project/node_modules/lodash/index.js
// yarn: /project/node_modules/lodash-es/lodash.js
// pnpm: /project/node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/

CI Environment Death Roulette

Randomly switching package managers in CI scripts turns automated builds into a heart-pounding game:

# .github/workflows/test.yml
steps:
  - name: Install dependencies
    run: |
      case $((RANDOM % 3)) in
        0) npm install ;;
        1) yarn ;;
        2) pnpm install ;;
      esac
      
  - name: Test
    run: npm test # Using npm to run tests is the last act of kindness

Team Collaboration Tower of Babel

The onboarding instructions for new team members require an epic-length guide:

1. Clone the repo
2. Run `rm -rf package-lock.json yarn.lock pnpm-lock.yaml`
3. Roll a die to decide which package manager to use:
   - 1-2: `npm install`
   - 3-4: `yarn install`
   - 5-6: `pnpm install`
4. If errors occur, repeat steps 2-3
5. Commit your generated lock file to git

Dependency Hell's Ultimate Form

When a project contains npm-shrinkwrap.json, yarn.lock, and pnpm-lock.yaml simultaneously, dependencies enter a quantum entanglement state:

// This import could point to any version
import React from 'react';

// Possible outcomes:
// - React 15 (from npm)
// - React 16 (from yarn)
// - React 17 (from pnpm)
// - Or a quantum superposition of all three

Module Resolution Dark Forest

Node.js's module resolution algorithm produces different results under different package managers, turning dynamic imports into a dark forest of suspicion:

require('module-alias/register'); // This plugin behaves entirely differently in all three environments

// The following path resolution might succeed, fail, or point to a completely different file
const utils = require('@project/utils');

Performance Benchmark Perpetual Motion

Team members waste hours daily arguing over package manager performance benchmarks:

# Benchmark scripts never reach a consensus
$ time (npm install && rm -rf node_modules)
real    1m12.34s

$ time (yarn install && rm -rf node_modules) 
real    0m45.67s

$ time (pnpm install && rm -rf node_modules)
real    0m30.12s

Security Vulnerability Tetris

Different package managers produce different security vulnerability reports, turning fixes into a game of whack-a-mole:

$ npm audit
found 42 vulnerabilities (12 critical)

$ yarn audit
found 38 vulnerabilities (8 high)

$ pnpm audit
found 56 vulnerabilities (3 critical, 19 moderate)

Dependency Uninstall Chaos Magic

Uninstalling dependencies behaves like different schools of magic:

# npm leaves traces behind
$ npm uninstall lodash
# Check to find lodash's relatives still in node_modules

# yarn's uninstall is pure mysticism
$ yarn remove lodash
# Sometimes unrelated dependencies vanish too

# pnpm's uninstall is terrifyingly thorough
$ pnpm remove lodash
# All related dependencies evaporate

Cross-Platform Hellscape

Mixing package managers across operating systems creates dimensional rifts:

# In Windows PowerShell
npm install --global yarn pnpm  # Install all managers globally

# Then discover PATH conflicts
yarn : The script yarn.ps1 cannot be loaded because running scripts is disabled on this system

Version Number Anarchy

Different package managers handle version numbers differently, turning ^ and ~ into hazardous symbols:

{
  "dependencies": {
    "react": "^16.8.0"  
    // npm might install 16.8.6
    // yarn might install 16.9.0
    // pnpm might install 16.8.0
  }
}

Local Development Schrödinger's Cat

Mixing npm link, yarn link, and pnpm link creates quantum entanglement:

# Developer A
$ cd my-package && npm link

# Developer B
$ cd ../main-project && yarn link my-package

# Developer C
$ pnpm install && pnpm link my-package

# Final result: require('my-package') could point to any version

Cache Purge Ritual Magic

When dependency installation fails, purging caches requires elaborate ceremonies:

# Full cleanup ritual:
npm cache clean --force
yarn cache clean
pnpm store prune
rm -rf node_modules
rm package-lock.json yarn.lock pnpm-lock.yaml
sudo reboot  # The most crucial step

Dependency Tree Parallel Universes

npm ls, yarn list, and pnpm list display three entirely different dependency trees:

$ npm ls lodash
lodash@4.17.21

$ yarn list lodash
└─ lodash@4.17.15

$ pnpm list lodash
└─ lodash@4.17.10

Global Install Dark Matter

Globally installed packages form parallel universes under different managers:

# Install globally with npm
$ npm install -g create-react-app

# Check with yarn
$ yarn global list  # Can't find the package

# Check with pnpm
$ pnpm list -g  # Shows packages from another dimension

Workspace Multiple Personality Disorder

Using workspace features in monorepos with different package managers induces schizophrenia:

{
  "workspaces": [
    "packages/*",   // npm/yarn style
    "apps/**"       // pnpm style
  ]
}

Package Publishing Quantum Fluctuation

Publishing packages with different managers produces varying results, like quantum observation:

# npm publish might include certain files
$ npm publish

# yarn publish might include others
$ yarn publish

# pnpm publish yields a third outcome
$ pnpm publish

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.