[패키지매니저를 알아보자] NPM, YARN, YARN BERRY, PNPM

개요

대부분 패키지 매니저의 기능은 동일합니다. 패키지 매니저들이 가진 주요 컨셉들은 다음과 같습니다.

  • 메타 데이터 처리 및 쓰기
  • 모든 의존성을 일괄(Batch) 설치 및 업데이트
  • 의존성 추가, 업데이트 및 제거
  • 스크립트 실행
  • 패키지 배포(publish)
  • 보안 감사(audit) 수행

우리는 패키지 매니저를 결정할 때 보편적으로 설치속도, 스토리지 사용량, 기존 워크플로우와 결합되는 방식 등 기능 외적인 요구사항을 기준으로 사용할 패키지 매니저를 결정하게 됩니다.
 
전통적으로 npm과 yarn classic은 flat한 node_modules 폴더에 의존성을 설치했었고, 이는 유령 의존성 및 node_modules의 저장공간 등의 문제로 인해 비판이 존재했었으며 이는 기존의 문제를 해결하는 패키지 매니저들의 등장으로 이어지게 된 것이죠.
 

NPM(Node pkgmakeinst)

npm이 등장하기 이전, 프로젝트에 필요한 의존성들을 수동으로 다운로드하고 관리를 했었습니다. 
저도 CDN을 통해 프로젝트에 필요한 의존성들을 가져온 경험이 있는데요, 더 크고 복잡한 프로젝트에서는 의존성을 직접 설치하고 관리하는 것이 매우 번거로울 것입니다. (어쩌면 의존성 관리를 위한 직무가 생겼을지도 모르겠네요...)
 
npm의 등장 이후, 의존성들을 손쉽게 관리할 수 있게 되었으며 지금까지도 사용되는 여러 컨셉들을 만들어냈습니다.
메타데이터를 가지고 있는 `package.json`, 의존성들을 `node_modules`라는 폴더에 설치한다는 개념, public/private 패키지 레지스트리와 같은 개념들 모두 npm에 의해 도입이 되었습니다.


Yarn Classic (Yarn 1.x)

npm이 가지고 있던 일관성, 보안, 성능 문제 등을 해결하기 위해서 나온 패키지 매니저입니다.  
yarn은 npm을 기반으로 프로세스를 설계했습니다. 하지만 당시 npm의 문제점 중 하나였던 설치 프로세스의 속도를 높이기 위해 작업을 병렬화했습니다. 또한 다음과 같은 개념을 패키지 매니저에 도입했습니다.

  1. native 모노레포 지원
    yarn classic에서는 workspaces 기능을 통해 모노레포를 지원합니다. 이 기능을 통해 여러 패키지를 단일 리포지토리에서 관리하고 종속성을 효율적으로 처리할 수 있습니다. 
  2. cache-aware 설치
    yarn classic은 패키지 설치시 이미 다운로드한 패키지를 로컬 캐시에 저장하고 동일한 패키지를 재설치할 때 이 캐시를 활용합니다. 이를 통해 네트워크 요청을 최소화하고 설치 속도를 향상시킵니다.
  3. 오프라인 캐싱
    yarn clasic에서는 yarn.lock 파일과 로컬캐시를 사용하여 오프라인에서도 패키지를 설치할 수 있습니다. 이미 설치한 패키지를 캐시에 저장해두었다가 인터넷 연결없이도 이 캐시를 사용하여 패키지를 재설치할 수 있습니다.
  4. lock files
    yarn classic에서 yarn.lock 파일은 프로젝트의 의존성 트리와 각 패키지의 정확한 버전을 고정하여 기록합니다. 이를 통해 모든 개발자가 동일한 의존성 트리와 패키지 버전을 사용하도록 보장할 수 있으며 프로젝트의 일관성을 유지할 수 있습니다.

Yarn Classic에서 캐시는 기본적으로 로컬 파일 시스템에 저장되어있습니다.
Mac을 기준으로 Yarn의 캐시 디렉토리를 확인하려면 다음과 같은 명령어를 입력하면 됩니다.

yarn cache dir
> /Users/devlee/Library/Caches/Yarn/v6

ls 
> 캐시된 라이브러리 리스트가 나온다...!

 
yarn classic은 2020년부터 유지보수 모드로 전환되었고, 현재는 yarn berry에서 개발과 개선이 이뤄지고 있습니다.


Pnpm

pnpm은 npm의 drop-in replacement로, npm만 있다면 바로 사용할 수 있습니다. 

- drop-in replacement: 설정을 바꿀 필요없이 바로 사용가능하며 속도와 안정성 등 다양한 기능 향상이 이뤄지는 대체품

 
npm과 yarn의 가장 큰 문제로 여겨졌던 부분은 프로젝트 간 사용되는 dependencies의 중복 저장이었습니다. npm과 yarn, 두 매니저 모두 node_modules 내부에 flat하게 패키지를 설치하여 관리했습니다.
 
pnpm은 이러한 호이스트 방식(flat 방식) 대신 content-addressable storage를 사용했습니다.
이 방법을 사용하면, home 폴더의 글로벌 저장소인(`~/.pnpm-store`)에 패키지를 저장하는 중첩된 node_modules 폴더가 생성됩니다. 따라서 모든 버전의 dependencies은 해당 폴더에 물리적으로 한 번만 저장되므로 single source of truth를 구성하고 디스크 공간을 절약할 수 있습니다. 
 
1) `pnpm store`의 개념

  • Global Store: `pnpm`은 모든 패키지를 중앙화된 전역 저장소에 저장합니다. 이 저장소는 기본적으로 `~/.pnpm-store` 디렉토리에 위치하며 시스템에 있는 모든 프로젝트가 이 저장소를 공유합니다.
  • 중복 방지: 같은 버전의 패키지가 여러 프로젝트에서 필요할 때, `pnpm`은 해당 패키지를 이 전역 저장소에 한 번만 다운로드하고 이후 모든 프로젝트에서 이 저장소를 참조하도록 합니다.

 
2) 패키지 저장 방식

  • 패키지 저장 구조: 패키지 파일들은 패키지의 내용을 기반으로 한 해시값을 사용하여 저장됩니다(해시 경로)
  • Content-addressable Storage (CAS): 이 구조는 동일한 내용의 패키지를 중복 없이 관리하기 위해 고안된 것입니다. 동일한 해시값을 가지는 패키지는 여러 번 저장되지 않고, 동일한 해시값으로 참조되므로, 같은 패키지가 여러 프로젝트에서 사용되더라도 디스크 공간을 추가로 차지하지 않습니다

 
3) 프로젝트 `node_modules`와 하드링크

  • 하드링크 사용: pnpm은 전역 저장소에서 각 프로젝트의 node_modules로 패키지 파일을 복사하는 대신, 하드링크를 사용하여 참조합니다. 하드링크는 파일 시스템에서 동일한 파일 데이터에 대한 여러 참조를 가능하게 하며, 여러 프로젝트가 같은 파일을 공유할 수 있게 해줍니다. 이는 디스크 공간 절약과 더불어, 패키지 설치 속도도 높여줍니다.
  • 프로젝트 내의 `node_modules`: 프로젝트의 node_modules 디렉토리에는 실제 패키지 파일들이 저장된 것이 아니라, 전역 저장소의 파일들을 가리키는 하드링크가 존재합니다. 이 방식 덕분에, 같은 패키지가 여러 프로젝트에서 사용되더라도 디스크 공간을 추가로 차지하지 않습니다.

CAS 공간 확인해보기

> pnpm store path # 이 명령어를 통해 CAS를 찾기
/Users/devlee/.pnpm-store/v3

> cd /Users/devlee/.pnpm-store/v3 # 이동하기

> cd files 

> ls 
00 0a 14 1e 28 32 3c 46 50 5a 64 6e 78 82 8c 96 a0 aa b4 be c8 d2 dc e6 f0 fa
01 0b 15 1f 29 33 3d 47 51 5b 65 6f 79 83 8d 97 a1 ab b5 bf c9 d3 dd e7 f1 fb
02 0c 16 20 2a 34 3e 48 52 5c 66 70 7a 84 8e 98 a2 ac b6 c0 ca d4 de e8 f2 fc
03 0d 17 21 2b 35 3f 49 53 5d 67 71 7b 85 8f 99 a3 ad b7 c1 cb d5 df e9 f3 fd
04 0e 18 22 2c 36 40 4a 54 5e 68 72 7c 86 90 9a a4 ae b8 c2 cc d6 e0 ea f4 fe
05 0f 19 23 2d 37 41 4b 55 5f 69 73 7d 87 91 9b a5 af b9 c3 cd d7 e1 eb f5 ff
06 10 1a 24 2e 38 42 4c 56 60 6a 74 7e 88 92 9c a6 b0 ba c4 ce d8 e2 ec f6
07 11 1b 25 2f 39 43 4d 57 61 6b 75 7f 89 93 9d a7 b1 bb c5 cf d9 e3 ed f7
08 12 1c 26 30 3a 44 4e 58 62 6c 76 80 8a 94 9e a8 b2 bc c6 d0 da e4 ee f8
09 13 1d 27 31 3b 45 4f 59 63 6d 77 81 8b 95 9f a9 b3 bd c7 d1 db e5 ef f9

 

Symbolic Link와 Hard Link란?

 

1) Inode란?

Inode(아이노드)은 스 파일 시스템에서 파일과 디렉터리를 식별하고 관리하는데 사용되는 데이터 구조입니다. 각 파일이나 디렉터리는 시스템 내의 고유한 Inode를 가지고 있습니다. Inode는 파일의 메타데이터 정보를 저장하며, 이 정보에는 파일의 권한, 소유자, 크기, 생성 시간, 수정 시간, 링크 수 등이 포함됩니다.

 

Inode가 가지고 있는 정보

inode가 가지고 있는 정보 설명
inode 번호 inode의 고유 식별 번호입니다
파일 모드 16비트의 플래그로 파일 실행 권한
소유자의 권한, 소유자 그룹의 권한, 기타 사용자의 권한, 파일 형식, 실행 플래그 등을 나타냅니다
링크 수 아이노드에 대한 참조 수를 나타냅니다
소유자 아이디 파일의 소유자 아이디를 나타냅니다
그룹 아이디 파일 소유자의 그룹아이디를 나타냅니다.
파일 크기 파일의 크기를 나타냅니다.
파일 주소 실 데이터가 나오는 파일 주소를 나타냅니다.
마지막 접근 마지막으로 파일에 접근한 시간을 나타냅니다.
마지막 수정 마지막으로 파일을 수정한 시간을 나타냅니다.
아이노드 수정 마지막으로 아이노드를 수정한 시간을 의미합니다.

 

`ls` 명령어에서 `-i` 옵션은 inode 번호를 같이 보여줍니다. 그래서 inode 번호와 같이 자세한 출력은 원하면 `ls -li`을 입력하면 됩니다.

 

2) Hard Link란?

하드링크는 리눅스 및 유닉스 기반 운영 체제에서 파일에 대한 추가의 파일 이름(경로)을 생성하는 메커니즘입니다.

이는 기본적으로 같은 Inode 번호를 공유하는 2개의 파일 엔트리를 만들어냅니다. Inode는 파일의 메타데이터와 데이터 블록의 위치 등을 저장하는 구조체로 파일 시스템에서 각 파일이나 디렉터리마다 부여되는 고유한 식별자입니다.

 

하드링크의 특징

  • Inode을 공유: 하드링크는 원본 파일과 새로운 하드링크 간에 같은 Inode를 공유하므로 같은 파일의 서로 다른 이름입니다.
  • 디스크 공간 절약: 하드링크를 생성하더라도 실제 데이터는 한 번만 디스크에 저장됩니다. 파일이나 디렉터리 크기에 상관없이 링크수만 증가하게 됩니다.
  • 링크 삭제와 파일의 실제 삭제: 모든 하드링크가 삭제되면(링크 수가 0이 될 때) Inode와 관련된 실제 데이터 블록이 디스크에서 해제되며 파일이 삭제됩니다.
  • 원본 파일과 링크간 동기화: 하드링크를 통해 파일을 수정하면 다른 모든 하드링크에서도 동일한 내용을 볼 수 있습니다. 동일한 Inode를 공유하므로 하나의 위치를 수정하면 나머지도 수정된 내용을 반영하게 됩니다.
  • 하드 링크 제한: 디렉터리에 대한 하드링크는 일반적으로 허용되지 않습니다. 디렉터리가 트리구조를 형성하고 있어 하드링크로 인한 순환참조 등의 문제를 방지하기 위함입니다.

하드 링크를 생성하는 명령어는 `ln`입니다. 

ln file.txt file_link.txt

file.txt 파일에 대한 하드링크를 file_link.txt로 생성하는 명령어이먀, file.txt와 file_link.txt는 동일한 파일의 서로 다른 이름이며, 하나를 수정하면 다른 하나에도 영향을 미칩니다.

 

[하드 링크에 대한 예시]

 

3) Symbolic Link란?

심볼릭 링크(Symbolic Link / Symlink)는 리눅스와 유닉스 기반 운영체제에서 파일이나 디렉터리에 대한 간접적인 참조를 만드는데 사용되는 파일입니다. 심볼릭 링크는 원본 파일이나 디렉터리의 경로를 가지고 있으며 이 경로를 통해 원본 파일이나 디렉터리에 대한 참조를 제공합니다.

 

심볼릭 링크 특징

  • 파일 크기: 심볼릭 링크 파일은 원본 파일의 경로를 저장하고 있기 때문에 매우 작은 크기를 가지고 있습니다. 이 크기는 저장된 경로의 길이에 의해 결정됩니다.
  • Inode 공유하지 않음: 심볼릭 링크는 원본 파일과는 다른 Inode를 가집니다. 따라서 별도의 파일 엔트리이며 원본파일과 다른 메타데이터를 가질 수 있습니다.
  • 원본 파일이나 디렉터리의 경로 저장: 심볼릭 링크는 원본 파일이나 디렉터리에 대한 경로를 저장하고 있으며 이 경로를 통해 실제 파일에 대한 간접적인 참조를 제공합니다.
  • 링크 삭제와 원본 파일: 원본 파일이나 디렉터리가 삭제되면 심볼릭 링크는 유효하지 않게 됩니다. 하지만 원본 파일이나 디렉터리를 삭제하지 않고 심볼릭 링크만 삭제한다면 원본 파일은 그대로 남아있습니다.
  • 하드링크 제한 없음: 심볼릭 링크는 파일이나 디렉터리에 대한 간접적인 참조를 제공하므로 하드링크와 달리 디렉터리에 대해서도 생성이 가능합니다.
  • 순환참조 가능: 심볼릭 링크는 경로를 가지고 있기 때문에 서로 다른 파일이나 디렉터리를 가리키는 링크간에 순환참조가 발생할 수 있습니다.

심볼릭 링크를 생성하는 명령어는 `ln`과 `-s` 옵션을 통해 심볼릭 링크를 생성할 수 있습니다.

ln -s /path/to/original/file /path/to/symlink

 

이 명령어는 /path/to/original/file에 대한 심볼릭 링크를 /path/to/symlink로 생성합니다.

 

 

[심볼릭 링크에 대한 예시]

 

 

[구조] 

CAS: 의존성(패키지, 라이브러리)의 원본

`node_modules`: 가상 저장소에 있는 의존성에 심볼릭 링크로 연결이 됩니다.

가상 저장소(Virtual Store): `node_modules` 내부의 `.pnpm` 폴더이며 CAS 내부의 의존성(라이브러리)과 하드링크를 갖는다.


Yarn Berry 

yarn berry는 yarn classic의 업그레이드 버전입니다.  
yarn berry는 plug n play로 의존성을 관리합니다. 기본적으로 node_modules를 생성하는 대신 `.pnp.cjs`라 불리는 의존성 lookup 파일이 생성되는데 이는 중첩된 폴더 구조 대신 단일 파일이므로 더 효율적으로 처리할 수 있습니다. 
또한, 모든 패키지는 `.yarn/cache` 폴더 내부에 zip 파일로 저장되므로 node_modules 폴더보다 더 디스크 공간을 더 적게 차지합니다.
 
1) 패키지 압축: Yarn Berry는 설치된 패키지를 .zip 파일로 압축하여 저장합니다. 이 압축은 단순히 파일을 작은 크기로 만드는 것 이상의 효과를 가져옵니다.

  • 압축된 상태로 저장: 일반적으로, 패키지 관리자는 수천 개의 파일을 각 패키지에 포함된 폴더에 저장합니다. Yarn Berry는 이러한 파일들을 .zip 파일로 압축하여 하나의 압축된 아카이브로 저장합니다. 압축을 통해 파일 크기를 줄여 디스크 공간을 절약할 수 있습니다.
  • 파일의 중복 제거: 동일한 파일이 여러 패키지에 포함된 경우가 자주 발생합니다. Yarn Berry의 압축 방식은 중복 파일을 효율적으로 관리하여 추가적인 디스크 공간 절약을 제공합니다

 
2) Zero-install와 Pnp (Plug'n Play): Yarn Berry의 Zero-Installs와 PnP 기능은 .zip 파일 시스템과 결합되어 디스크 사용량을 더욱 최적화합니다.

  • Zero-Installs: Yarn Berry는 node_modules 폴더를 생성하지 않고, `.yarn/cache` 폴더에 의존성의 정보가 저장되고, `.pnp.cjs` 파일에 의존성을 찾을 수 있는 정보가 기록됩니다. 이 파일은 패키지의 의존성을 관리하고, 각 패키지의 실제 파일을 가리키는 역할을 합니다. 이는 기존 방식에서 수많은 개별 파일로 구성된 node_modules 폴더가 차지하는 공간을 크게 줄입니다.
  • PnP: PnP 시스템은 패키지를 필요할 때 메모리에 직접 로드하여 실행합니다. 이 과정에서 .zip 파일에서 패키지를 읽고 바로 사용할 수 있어, 압축된 상태로 저장된 패키지들이 실제로 해제되지 않고도 사용될 수 있습니다.

 

Yarn berry는 다른 Node.js 의존성 관리 시스템과 다르기 때문에 하위호환을 위해 패키지 단위로만 도입할 수 있습니다 .

 

Yarn Berry 환경은 단순 자바스크립트 파일일 뿐입니다. 

 

1) Yarn Classic

Homebrew를 통해 Yarn을 설치하게 되면,  Yarn 패키지는 로컬 PC 내에서 Global Package 공간 어딘가에 저장이 되고 이후에 터미널 내의 커맨드를 통해 실행시킬 수 있습니다. 

터미널 내에서 yarn으로 시작하는 명령어를 수행할 수 있다는 뜻은 OS 내 Shell 스크립트 형식으로 사용할 수 있는 명령어로 OS 인터페이스를 통해 수행할 수 있는 명령어라는 뜻입니다.

 

2) Yarn Berry

yarn berry 환경을 세팅할 때를 생각해보면 로컬 자체에 Yarn Berry를 세팅하는 것이 아닌 특정 프로젝트 환경 아래에서 명령어를 통해 Berry 환경을 세팅합니다.

// 방법 1

// 코어팩 설정
corepack enable
corepack prepare yarn@4.4.0 --activate

// 프로젝트 내의 yarn 버전을 berry로 설정
yarn set version berry

// yarn 실행
yarn


// 방법 2
yarn init -2

 

이에 대한 증거로 yarn berry에서 package.json 내 명시한 script로 환경변수를 주입하기 위해 `export` 명령어를 시도하면 오류가 발생합니다.

 

// package.json

{
  "scripts": {
    "dev": "export NODE_ENV=development && node server/index.mjs",  
   }
}


// 터미널
$ yarn dev
command not found: export

 

yarn classic에서는 정상적으로 동작하던 export 명령어가, yarn berry에서 동작하지 않는 이유는, `export` 명령어가 OS 인터페이스 명령어 이므로, yarn classic 환경에서 package.json 내 선언된 script로 export 명령어를 수행한다면 그냥 일반적인 CLI로 동작하는 것이므로 수행이 가능한 것입니다. 그러나 yarn berry에서는 package.json 내의 script가 yarn-3.2.3.cjs라는 자바스크립트 파일로 동작하는 것이죠. 

자바스크립트 파일 자체가 로컬 환경의 인터페이스를 통해 환경 변수를 주입하는 것은 불가능하기 때문에 인터페이스 명령어인 `export` 커맨드를 사용할 수 없는 것입니다. 

 

Yarn berry 환경에서 수행되는 Yarn 명령어는 모두 yarn-3.2.3.cjs라는 JS 파일에서 동작합니다.

그렇다면 개발자가 Yarn 명령어를 수행하면 어딘가에 yarn-3.2.3.cjs를 동작시키는 Yarn 명령어는 어떤 존재일까요?

 

Yarn Berry는 Yarn Classic 환경 위에서 동작함

JS 파일을 실행하는 것이 로컬 환경 자체에 CLI로 동작하는 Yarn Classic입니다.

 

Yarn Berry 환경에서 우리가 터미널에서 수행한 yarn 커맨드는 yarn berry가 아닌 yarn classic이고, yarn classic이 프로젝트가 yarn berry 환경인지 파악후 yarn.3.2.3.cjs 파일을 실행시킵니다.

 

그러나 이런 동작 방식으로 인해, Yarn Berry에서 다른 패키지들을 동작시킬 때 의도치 않게 Berry를 통해 수행되지 않아 정상적으로 동작하지 않는 이슈가 발생할 수 있습니다. 이를 위해서 Yarn에서는 `yarn dlx` 커맨드를 통해 임시 환경 위에서 패키지를 수행할 수 있는 기능을 제공합니다.


Corepack이란?

Corepack은 Node.js와 함께 제공되는 패키지이며, 주요 패키지 관리자들을 쉽게 사용할 수 있도록 돕는 기능을 제공함. 이 기능이 있으면 Yarn, pnpm 같은 패키지 관리자를 별도로 설치하지 않고도 사용할 수 있음.
Corepack은 프로젝트의 package.json에 명시된 버전에 맞는 패키지 관리자를 자동으로 설치하고 사용할 수 있게 해줍니다.
이 도구는 다양한 패키지 관리자(Yarn Classic, Yarn Berry, pnpm 등)의 shim(셈) 버전을 제공하여, 사용자가 이들 패키지 관리자를 직접 설치하지 않고도 바로 사용할 수 있게 합니다.
 
Shim이란?

  • Shim은 기본적으로 특정 프로그램이나 명령어를 호출할 때, 해당 프로그램의 실제 바이너리가 아닌 중간에 존재하는 "가상" 바이너리를 의미합니다.
  • Corepack이 제공하는 shim은 Yarn이나 pnpm 명령어를 호출할 때, 해당 명령어를 감싸는 중간 프로그램 역할을 합니다.
  • 이 shim은 프로젝트의 설정에 따라 적절한 패키지 관리자 버전을 자동으로 선택하고 실행합니다

Corepack의 Shim 원리
Node.js의 Corepack에서 사용하는 Shim은 Yarn, pnpm 등의 패키지 관리자 명령어를 실행할 수 있도록 도와줍니다. 

  1. Shim 생성 및 배포:
    • Corepack이 포함된 Node.js 설치 시, Yarn과 pnpm의 Shim 파일이 시스템에 함께 설치됩니다. 이 Shim 파일들은 yarn, pnpm 명령어를 가로채는 역할을 합니다.
  2. 명령어 실행 시 동작:
    • 사용자가 터미널에서 yarn 또는 pnpm 명령어를 입력하면, 시스템은 해당 명령어의 실제 위치를 찾습니다. 이때, Shim 파일이 존재하면 이 파일이 먼저 실행됩니다.
    • Shim은 현재 프로젝트의 루트 디렉토리에 있는 package.json 파일을 읽고, 그 안에 명시된 패키지 관리자 버전 정보를 확인합니다.
    • 필요한 버전이 이미 로컬에 설치되어 있으면, 그 버전을 사용하여 명령어를 실행합니다. 만약 설치되어 있지 않으면, Corepack이 자동으로 해당 버전을 다운로드하여 실행 환경을 구성한 후, 명령어를 실행합니다.
  3. 명령어 전달:
    • Shim은 해당 명령어에 필요한 모든 설정을 처리한 후, 명령어와 함께 전달된 모든 인수를 실제 패키지 관리자 프로그램에 전달합니다.
    • 이렇게 함으로써 Shim은 사용자와 실제 패키지 관리자 프로그램 사이에 있는 중간 레이어 역할을 하게 됩니다.

corepack 사용 예시

corepack enable
corepack prepare yarn@3.1.1 --activate

 

  1. `corepack enable`: corepack을 활성화하는 명령어입니다. 활성화되면 Corepack은 Yarn, pnpm 등의 패키지 관리자를 다루는 Shim을 시스템에 설정합니다. 
  2. `corepack prepare yarn@3.1.1 --activate`: 특정 버전의 패키지 관리자를 다운로드하고 활성화하는 역할을 합니다.

실습

 
Yarn
 
Pnpm
작성중...!
 
 
 


출처 

https://www.youtube.com/watch?v=YWnH0M-p_H4&t=182s

https://pnpm.io/ko/symlinked-node-modules-structure

 

symlink된 `node_modules` 구조 | pnpm

This article only describes how pnpm's node_modules are structured when

pnpm.io

https://velog.io/@rladmlduq47/Symbolic-Link-Hard-Link%EB%9E%80

 

Symbolic Link & Hard Link란?

Inode(아이노드)은 리눅스 파일 시스템에서 파일과 디렉터리를 식별하고 관리하는 데 사용되는 데이터 구조입니다. 각 파일이나 디렉터리는 시스템 내의 고유한 Inode를 가지고 있습니다. Inode는

velog.io

https://yceffort.kr/2022/05/npm-vs-yarn-vs-pnpm#%EC%84%A0%EA%B5%AC%EC%9E%90-npm

 

npm, yarn, pnpm 비교해보기

Table of Contents Introduction npm 에서 시작한 node package management의 역사는, 이제 3가지 옵션이 주어져 있다. yarn 1.0 (이제 yarn classic 이라고 부르겠다) 과 yarn 2.0 (yarn berry) 두 가지 버전도 사뭇 다른 점이

yceffort.kr

 https://lasbe.tistory.com/200