거의 알고리즘 일기장

pnpm이 뭔가여? 본문

web

pnpm이 뭔가여?

건우권 2022. 12. 23. 02:19

최근 tuborepo document를 읽다가 package manager는 pnpm을 쓰는것을 적극 권장하는걸 보고 호기심이 들어 서칭해보았다.

이 글은 그것을 정리해놓은 글이다.


pnpm?

npm, yarn과 같은 package manger다.


만들어진 동기

이미 npm, yarn이 존재하는디? 왜 만듬?

 

1. npm v3 전 버전의 package를 관리하는 방식의 문제점이 있었다.

 1) module의 중복

 2) 너무 깊은 종속성 트리로 인한, 디렉토리 경로 문제

node_modules를 사용할때 자주 이용하는 그림

2. npm v3 부터 이 문제를 해결하기 위해 root로 평탄화함으로써 중복을 줄였다. (hoisting 함) 그리고 이건 yarn v1 도 마찬가지다.

flat한 node_moudles 방법

이로써 yarn v1, npm flat한 node_modules 한 방법을 이용하게 되었다.

 

그러면 모든 문제가 해결되었을까?

이 구조의 채택으로 인한 문제가 또 생겼다.

 

바로! 유령의존성이다.

예시를 들자면, 나는 a, b package만 추가했는데.. a의 의존 package인 c package도 우리의 코드에서 사용할수 있는 이상한 현상이다. 

ㄱㅇㄷ?

현생에서는 ㄱㅇㄷ이겠지만,

소프트웨어 개발의 세계에서는 사용하겠다고 명시하지 않은 package를 불러올수 있다는건 버그의 가능성 존재한다는 것이므로 그리 좋지는 않다.

 

pnpm은 이러한 문제를 해결하기 위해서 나왔다!

 

자세한건 하단의 링크를 보면 좋다!

https://www.kochan.io/nodejs/why-should-we-use-pnpm.html

 

Why should we use pnpm? by @ZoltanKochan

Why should we use pnpm? 19 Mar 2017 · 5 min read · comments pnpm is an alternative package manager for Node.js. It is a drop-in replacement for npm, but faster and more efficient. How fast? 3 times faster! See benchmarks here. Why more efficient? When yo

www.kochan.io


어떻게 해결함?

이제 무엇을 해결하기 위해서 pnpm이 나왔는지 감이 잡힐것이다.

 

그러면, 어떻게??.. 해결했다는걸까?

 

1. pnpm은 project에 직접적인 dependency만 moudle directory의 root로 추가한다.

2. module의 duplicate를 막기 위해 symlink를 통해 방지한다.

pnpm 홈페이지

 

이렇게 글로만 들으면 이해가 가지 않을테니, 간단한 예시를 준비했다.


예시

프로젝트의 상태

//pnpm으로 express, cookie, lodash, qs를 Install 한 상태
//express는 cookie, qs를 dependency로 가진다.
{
  "name": "pnpm-test",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cookie": "^0.5.0",
    "express": "^4.18.2",
    "lodash": "^4.17.21",
    "qs": "^6.11.0"
  }
}

node_modules

node_modules
|- .pnpm
|    |
|    |-express@version, cookie@version, lodash@version
|
|- express ./.pnpm/express@version/node_module/express의 가상본
|- cookie ./.pnpm/cookie@version/node_module/cookie의 가상본
|- lodash ./.pnpm/lodash@version/node_module/lodash의 가상본
|- qs ./.pnpm/qs@version/node_module/express의 가상본

index.js in node_modules/express 에서 현재 위치 path 확인시

//root app.js에서 resolve.paths("express")
[
  '/Users/kunwookwon/Study/pnpm-test/node_modules', // <- 이곳에 express의 가상본이 존재
  '/Users/kunwookwon/Study/node_modules',
  '/Users/kunwookwon/node_modules',
  '/Users/node_modules',
  '/node_modules',
  '/Users/kunwookwon/.node_modules',
  '/Users/kunwookwon/.node_libraries',
  '/opt/homebrew/Cellar/node@14/14.21.1/lib/node'
]

'/Users/kunwookwon/Study/pnpm-test/node_modules/express의 index.js'

'use strict';

console.log(__dirname);

module.exports = require('./lib/express');

가상본임이 확인 가능함. 실제로는 저 위치에 원본이 존재

finder 에서 확인

원본은 .pnpm/{module}@{version}/node_modules/{module}에 존재


yarn v1, v2, npm, pnpm의 benchmark

https://github.com/pnpm/benchmarks-of-javascript-package-managers

 

GitHub - pnpm/benchmarks-of-javascript-package-managers: Benchmarks of JavaScript Package Managers

Benchmarks of JavaScript Package Managers. Contribute to pnpm/benchmarks-of-javascript-package-managers development by creating an account on GitHub.

github.com


pnpm...

이론적으론 yarn berry의 pnp 방식보다 더 깔끔하고 좋은 호환성을 가져가는 구조 같다!

하지만.. yarn berry보다 많이 보이지 않는 이유가 있을것 같다. 그건 나중에 알게되면 하단에 적어놓겠다. ㅋㅋ


참고

https://pnpm.io/ko/

 

Fast, disk space efficient package manager | pnpm

Fast, disk space efficient package manager

pnpm.io

 

반응형
Comments