주차 및 날짜: 2주차 (10/20)
담당자: 황수빈, 가영 이
라이브러리(library)와 유사한 개념
패키지를 다루는 작업을 편리하고 안전하게 수행하기 위해 사용되는 툴
package.json은 프로젝트 정보와 의존성(dependencies)을 관리하는 문서입니다.
우리가 어떤 패키지(오픈소스)를 사용하는지, 어떤 버전을 사용하는지 등을 기록함으로써 어느 곳에서도 동일한 개발 환경을 구축할 수 있게 해줍니다.
다시 말하자면 ⇒ 패키지를 사용하고자 할 때 dependency에 해당되는 다른 패키지들을 전부 설치해줘야한다
Node Packaged Manager ➡️ Node.js로 만들어진 pakage들을 관리해주는 툴
수정 ⇒
pm
은 node package manager
의 약자가 아니다. npm의 전신은 사실 pm
이라 불리는 bash 유틸리티인데, 이는 pkgmakeinst
의 약자다. 그리고 이의 node 버전이 npm
인 것이다.
https://github.com/npm/cli#is-npm-an-acronym-for-node-package-manager
npm이 없었을 때는 필요로 하는 기능을 추가하기 위해서 직접 작성하거나 github를 통해 다운로드하여 사용해야 했다. Node.js를 설치하기만 하면(기본적으로 npm은 Node.js 내에 내장) 명령어 한 줄로 기능의 추가가 가능
그렇다면 이렇게 편리한 npm이 있는데 yarn이라는 것은 왜 만들어지게 된 것일까요?
🔄 의존성 중복
패키지 설치 시 패키지들을 각각 별도로 설치
→ 공유된 의존성이 중복으로 설치될 수 있다. 의존성 트리가 깊어질수록 패키지 설치 속도가 느려지고, 디스크 공간을 많이 차지할 수 있다.
⛔ 일관적이지 않은 패키지 버전
시맨틱 버저닝 → 모듈간의 버전 불일치
로 인해 문제가 발생할 수도 있다.
1.2.3
처럼 버전을 세 가지 숫자가 들어갈 수 있는 자리로 구분하고, 각각의 자리에 현재 버전이 이전 버전과 어떤 관계가 있는지 암시하도록 하는 방법입니다. 예를 들어 첫 번째 자리에 들어가는 숫자가 다르면, 두 버전은 이전 버전과 호환되지 않는 완전히 새로운, 메이저 버전이라는 의미입니다. ^7.17.9
이므로, 메이저 버전인 7이 변경되지 않는 범위에서는 모듈의 버전이 바뀌는 것을 허용합니다. 7.17.10
버전이나, 7.18.0
버전 등이 모두 사용될 수 있다고 볼 수 있겠네요. 이때 npm install
명령어를 통해 모듈들을 설치하면 해당 메이저 버전 중 최신 버전을 다운받게 됩니다. 빌드에 따라 유연하게 버전을 선택할 수 있다는 장점도 있지만, 이럴 경우 사용하는 모듈간의 버전 불일치로 인해 문제가 발생할 수도 있습니다. 서로 다른 환경에서 하나의 프로젝트를 개발 한다는건 어떤 문제가 발생할지 모르는 잠재적인 위험을 안고 가는 것과 같습니다.🎢 속도 및 성능
npm은 모듈들을 한 번에 하나씩만 순차적
으로 설치 → 설치해야 하는 모듈이 많으면 많을수록, 총 설치 시간이 길어지게 됩니다. 첫 모듈 설치 시간이 길어지면 빌드 및 배포 시간에도 부정적인 영향을 끼치게 됩니다.
🔐 취약한 보안 이슈
과거의 npm은 잠금 파일
이 없었다 → 패키지 설치 시 자동으로 포함된 의존성 패키지가 설치되도록 함
(하지만 현재는 package-lock.json
을 제공)
🤦🏻 환경에 따라 달라지는 동작
고정되지 않은 설치 순서
→ 개발자의 환경에 따라 모듈들의 설치 순서가 변경될 수 있다. 이미 만들어진 프로젝트에서 모듈을 추가로 설치하게 될 경우, 그 뒤에 명령어를 통해 처음부터 설치하는 사람과 모듈 설치 순서가 달라질 수 있습니다. 내가 어떤 순서로 모듈을 의존성에 추가 했는지에 상관없이, npm은 모듈 이름을 사전 순서대로 정렬하여 순차적으로 설치하기 때문입니다.
기존의 npm이 가지고 있던 문제점들을 해결하기 위해 등장
yarn은 사용할 모듈의 버전을 지정하기 위해 프로젝트에 .lock
파일을 포함
정확한 버전을 지정하고 고정하기 때문에 다른 사용자가 프로젝트를 개발할때 항상 같은 버전의 모듈을 사용할 수 있도록 보장 이 파일 덕분에 기존 npm의 일관적이지 않은 패키지 버전 문제를 해결 가능
yarn은 캐시를 사용하여 한 번 다운로드 한 패키지라면 그 다음부터는 엄청나게 빠른 속도로 설치 가능, 인터넷이 연결되지 않은 환경에서도 설치가 가능(오프라인)
병렬 다운로드를 지원하여 순차적으로 설치해야하는 npm과 달리 모듈들을 한꺼번에 설치 → 속도 ↑
npm | → | yarn | |
---|---|---|---|
속도 | 순차적으로 설치로 인한 긴 소요시간 | Ultra Fast(고속), Offline Mode(오프라인모드) | 다운로드한 모든 패키지를 캐시화, 병렬화를 통해 리소스 활용률을 극대화 |
의존성 | 의존성 중복 | Flat Mode(플랫 모드) | 중복 항목을 생성하지 않으려면 일치하지 않는 버전의 종속성을 단일 버전으로 해결 |
신뢰성 | 일관적이지 않은 패키지 버전 | Super Reliable(신뢰성) | 잠금 파일 형식을 사용하여 다른 시스템에서도 동일한 방식으로 작동하도록 보장 |
접근성 | 별도 설치 X | 별도 설치 필요 |
npm은 기본적인 패키지 매니저이며,
pnpm은 npm의 의존성 문제를 해결한 패키지 매니저다.
yarn은 npm보다 빠른 의존성 설치와 버전 관리를 제공하는 패키지 매니저이며,
yarn berry는 다중 패키지 프로젝트를 위한 기능을 강화한 yarn의 버전이다
키워드 : #!flat , #심볼릭 링크 , #디렉토리 레벨
pnpm은 npm의 구조를 가져가는 명확하게 한 가지만 변경을 시켰다.
❤️ 바로 (평탄화 하지 않은) 플랫하지 않은 노드 모듈을 사용하겟다는 것.
위에서 pnpm 디렉토리 확인한 사진들을 보며 의존성들은 어디에 있을까?
node_modules
에는 .pnpm
이라는 하나의 폴더뿐이며 express
라는 심볼릭 링크만 있다.
의존성 :
Node.js는 패키지 의존성을 관리하기 위해package.json
파일에 정의된 의존성 목록을 사용한다. 이 목록은 패키지 이름과 해당 버전을 포함하고 있으며, npm (Node Package Manager) 또는 yarn과 같은 패키지 관리 도구를 사용하여 이 목록에 나열된 의존성을 설치한다.
일반적으로 패키지 관리 도구는 패키지를node_modules
디렉토리에 설치하여 이 디렉토리에 설치된 패키지는 프로젝트의 코드에서require
함수를 사용하여 불러올 수 있다.
express 안에 무엇이 있는지?
express
에는 node_modules
가 없다?
express
의 모든 의존성들은 어디에?
⭐ 사실
express
가 단지 심볼릭 링크라는 것!
→ 이게 무슨 말이냐… 그니까 Node.js는 actual location을 이용해서 사용된다.
즉, 패키지가 실제 파일 시스템의 복사본이 아닌 원래 위치에서 로드되는 것을 의미한다.
❤️ 심볼릭 링크(Symbolic Link),
일반적으로 "심링크"라고 줄여 부르며 "소프트 링크(Soft Link)" 또는 "심볼릭 링크(Symbolic Link)라 한다. 파일 시스템에서 사용되는 특별한 종류의 파일이며, 다른 파일이나 디렉토리를 가리키는 참조(링크) 역할을 한다.
- 가상 경로 참조:
심볼릭 링크는 다른 파일 또는 디렉토리의 가상 경로를 가리킨다. 즉, 원본 파일이나 디렉토리가 아닌, 그 목적지의 경로를 저장하고 있다.
즉 실제 위치는 아래 사진과 같은 곳에 저장되어 있다!
아 그래서 .pnpm/
폴더의 목적을 알게 되었다!
우리는 이를 가상 저장소 디렉토리라 부른다.
즉, 내가 이해한 바로는 .pnpm/
은 가상 저장소 디렉토리?!
→ npm v3,4,5,6 또는 Yarn v1에 의해 생성된 평탄한 node _modules
와는 달리 패키지를 격리된 상태로 유지한다.
❤️ pnpm에서 node_modules
구조의 두 번째 트릭은 패키지의 의존성들이 의존 패키지의 실제 위치와 동일한 디렉토리 레벨에 있다는 것.
따라서 express
의 의존성들은 npm의 의존성 문제를 해결하기 위해 고안된 패키지 매니저로, 고유 설치와 플랫 노드 모듈을 통해 의존성 관리를 최적화한다.
⭐ 무슨 말이냐면, 실제 위치를 프로젝트 루트 디렉토리에서부터 일정한 깊이(기본적으로 .pnpm디렉토리 내)에 저장하며, 이 위치에 대한 심볼릭 링크를 생성한다. 이것은 효율적으로 중복된 의존성을 공유하고 디스크 공간을 절약하는 방식인 것.
예를 들어, express
패키지의 의존성들이 pnpm
을 사용하는 경우, 이러한 의존성들은 .pnpm/express@4.17.1/node_modules/
디렉토리에 저장된다.
그리고 이러한 의존성들은 express
패키지에 대한 심볼릭 링크를 통해 참조된. 이것은 중첩된 의존성이 여러 번 복사되지 않고 효율적으로 관리됨을 의미한다.
결론 :
pnpm
을 사용하면 디스크 공간을 절약하면서도 패키지 의존성을 효율적으로 관리할 수 있습니다
만약 여러분이 npm과 yarn으로 프로젝트를 100개를 컴퓨터에 다운을 받는다 치면
노드 모듈이 컴퓨터에 100개가 다운받을 것 → 생각만해도 내 컴퓨터 눈물 줄줄이죠?
근데 pnpm은 이게 불필요하다 생각한거
pnpm을 설치하게 되면 루트 디렉토리에 pnpm store라는 레지스트리를 자체적으로 생성한다.
그래서 거기에 단 한 번만 저장을 하게 된다..? →전역적으로 관리하는 느낌으로 이해했다…
그러면 실제 프로젝트의 node_modules에는 이걸 연결하는 심볼릭 링크만 달아준다. 루트 디렉토리에 있는 pnpm store에 연결해서 가져오면 된다.
키워드 : #Plug’n’Play , #ZipFS , #Zero-Install
배경 :
즉, Node.js를 위한 새로운 패키지 관리 시스템으로, 기존의 npm, yarn v1의 패키지 비효율적인 매니징 방법을 개선하며 빌드 시간을 단축시켜주고 개발 과정에서의 안정성을 높여준다.
유령 의존성 (phantom dependencies) 즉, 어떠한 의존성이 호이스팅을 통해 최상단으로 선언되었다면, 실제로
package.json
에 선언되지 않은 패키지임에도 불구하고, 사용할 수 있는 문제점을 유령 의존성이라 한다.
문제점 :
1. package.json에 명시되지 않은 패키지 또한 사용가능해지는 경우가 생긴다.
2. package.json 패키지를 제거했을 경우 의존되는 내용도 함께 사라질 수 있다
yarn은 새로운 전략으로 이 문제를 해결하려 했고, pnp 방식을 선택하였다.
💻 PNP 방식 : 즉시 시작이라는 뜻, 꽂기만 하면 사용할 수 있다 정도로 풀어 쓸 수 있다. 의미는 컴퓨터에 하드웨어를 연결하면 별도의 사용자 조작이나 프로그램 설치 없이 바로 사용할 수 있는 것.
pnp 방식은 어떠한 패키지를 설치하게 되면 더 이상 node_modules
에 저장되지 않는다. 대신 .yarn/cache
폴더에 해당 의존성의 정보가 저장되고, .pnp.cjs 파일에 의존성을 찾을 수 있는 정보가 기록된다.
/* prettier 패키지 중에서 */
["prettier", [\
/* prettier 패키지의 버전이 2.8.8이고 npm 패키지로 등록되어있다. */
["npm:2.8.8", {\
/* 이 위치에 있고 */
"packageLocation": "./.yarn/cache/prettier-npm-2.8.8-430828a36c-b49e409431.zip/node_modules/prettier/",\
/* 이 의존성들을 참조한다. */
"packageDependencies": [\
["prettier", "npm:2.8.8"]\
],\
/* 실제 파일 시스템에 복사된다.(해당 패키지가 모듈로 사용되는 모든 위치에서 동일한 내용을 가짐) */
"linkType": "HARD"\
}]\
]],\
이제 각 의존성은 Zip 아카이브로 관리된다.
.zip를 활용하여 압도적으로 적은 용량 사용.
.pnp.js
에 명시된 정보에 따라서 각 패키지들은 동적으로 참조된다.
해당 방식을 택함으로서 기존의 node_modules
방식 때보다 사용 용량이 획기적으로 줄었다. 또한 기존의 트리형태의 node_modules
폴더를 순회할 필요가 없어졌기 때문에, 검색 속도도 증가!
yarn berry에서 패키지 정보를 zip으로 관리하는 이유는 다음과 같다.
- 용량 대폭 감소
- 변경 여부 확인 용이 (zip 파일의 checksum을 확인)
- 복잡한 구조가 필요 없음.
zero install은 말 그대로 설치를 하지 않고 이용하는 방식말한다.
기존에 node_modules에서 모든 디펜던시를 새로 인스톨하려고 하면, 모든 디펜던시 모듈이 인스톨에만 굉장히 많은 시간이 소모하게 되는데
zero install을 이용하면 디펜던시 install에 걸리는 시간을 없앨 수 있기 때문에 CI단이나 배포 파이프 라인에서 반복되는 install 시간을 단축시킬 수 있게 되고 CI 실행시간 및 배포 시간을 대폭 감소 시킬 수 있다.
.pnp.cis
: 의존성을 확인할 수 있는 파일
💻 결론 : zero-install을 통해 패키지의 의도하지 않은 호이스팅을 허용하지 않고 + install 시간 감소
문득, 초기세팅을 조사하던 중, 그래서 얘네들 개념은 잘 알겠다. 근데 어떨 때 써야 야무지게 쓸 수 있는지...궁금해졌기에 사례들로 같이 알아보자!
많은 글들을 알아본 결과
기존 방식을 버리고 새롭게 제시한 패러다임은 안정성을 보장할 뿐만 아니라 개발 워크플로우도 개선할 수 있기 때문입니다.
우선 zip 파일을 git으로 관리하기 시작하는 순간, 모두가 같은 버전의 패키지를 사용하는 게 보장됩니다. 각자 네트워크에서 패키지를 다운로드 받는 게 아니라 동일한 파일을 source로 사용하게 때문이죠.
Zip FS 특징은 CI/CD를 구축할 때도 장점으로 작용한다.
배포할 때 구조에 따라 과금 문제로 인해 서버 확장에 제약이 있다.
네트워크에서 패키지를 다운로드 받는 시간이 사라지므로 보통 분 단위로 과금하는 CI/CD 솔루션을 사용할 때 비용 절감 효과를 기대할 수 있습니다.
이런 것보다 나는
🤖 바로 브랜치를 넘나들 때마다 install을 굳이 할 필요가 없어진다는 점입니다.
이 말에서 pnp가 확 와닿았던 것 같다.
그래서 나도 협업 할 때 항상 배포하기 전엔 `npm install i`를 적극활용 했던 기억이..
하지만 PnP 방식에서는 패키지 zip 파일 자체를 버전관리할 수 있게 되어 각 커밋에 맞는 의존성이 생긴다고 이해했다.
어떤 브랜치, 어떤 커밋으로 돌아가도 ‘.yarn/cache’ 폴더에 즉시 사용 가능한 패키지들이 있다!
하지만 이것의 모든 전제는 모든 패키지가 PnP를 지원해야 한다는 점
🤖프로젝트에 PnP를 지원하지 않는 패키지가 하나라도 존재한다면 PnP 방식일지라도 node_modules가 따라온다. 흠...
막상 yarn berry 버전에서 pnp을 이용해 보면, 예상과는 다르게 정상적으로 동작하지 않고 디펜던시 관련 에러가 발생 할 것이다.
각 모듈이 pnp로 사용할 수 있으려면, pnp방식에 맞게 의존성 관리가 strict하게 세팅이 되어있어야 한다. 그러나 모든 모듈이 pnp형태에 맞게 호환이 모두 되어있는 상태가 아니기 때문에 pnp를 제대로 사용하기에는 많은 문제들이 발생할 수 밖에 없다.
🤖 이로 인해 Yarn에서도 완전히 strict한 방식 대신, pnp loose 모드를 통해 명시적으로 요구하는 디펜던시를 요구하지 않도록 할 수 있다.
그러나 이는 pnp가 정상적으로 동작하는 것을 보장하지 않는다. 따라서 왠만하면 pnp 모드를 이용하려면 strict 모드로 이용하는 것이 좋다.
각 의존성 모듈이 zip아카이브 파일로 독립적으로 관리가 됨으로써 의존성 트리가 더욱 strict하게 관리가 필요하다.
따라서 pnp형식으로 관리가 될 때는 이러한 의존성 모듈 관리에 대해 문제되는 부분을 모두 해결해 주어야만 정상적으로 pnp방식으로 모듈을 이용할 수 있게 된다.
매번 npm 또는 yarn으로 패키지 환경을 셋팅하면 git clone을 하면 npm install
및 yarn install
를 통해 의존성을 관리해야 했지만, 이런 점들이 zero-install로 하지 않아도 된다는 점. 유령 의존성 문제 극복점들은 매우 이상적인 것 같다.
하지만 막상 실제 도입 사례들을 찾아본 결과 느껴지는 단점은 모든 패키지가 PnP를 지원해야 한다는 점인 것 같다.
그래서 실제 적용 사례들을 보며 생각을 해봤다.
Airbridge가 pnpm으로 돌린 이유!
글을 읽어보면 Yarn-berry(PnP)의 문제점을 파악했다.
고민은 Airbridge의 커밋 수는 10,000건이 넘는다는 점이었습니다. Airbridge에서 사용하는 패키지 중에서는 바이너리가 포함된 무거운 패키지들이 있습니다. 커밋의 수가 많을 수록, 한 커밋에 포함되는 파일의 용량과 수가 많을 수록, 이후의 작업에서 Git의 체크아웃, 브랜칭 속도에 영향을 줄 수 있겠다는 생각이 들었습니다.
이를 풀기 위해 Git 대용량 파일 저장소(LFS) 내지는 Git 최대 커밋 크기 조정, 주기적으로 Git의 history를 살리면서 파일만 지우는 작업을 하는 것은 정말 오버 엔지니어링이라고 생각했습니다.혹은 Yarn Workspace의 자잘한 버그들
그리고, 모노레포 내의 패키지들에 얽힌 dependency를 별도로 설치, 관리해야했습니다.
이로 인해 저장 공간을 중복으로 사용하거나 설치 시간이 오래 걸리는 문제가 있었습니다.
사용후기들도 마찬가지로 찾아보았다.
Javascript 패키지 매니저 pnpm, pnpm이란?, pnpm사용이유, pnpm 설치방법, pnpm 사용방법
실제로 써보니 확실히 더 빠르게 프로젝트를 셋업할 수 있었습니다.
그리고 항상 node_modules 폴더 크기가 너무커서 불필요 프로젝트를 삭제할때마다 시간이 오래걸렸는데,
이 부분도 크게 향상되어서 만족스러웠습니다.
많은 개발자들이 npm, yarn, pnpm 모두 사용해도 좋을 만큼 안정적인 상태에 있다고 평가한다.
확실히
프로젝트 마다 다양한 패키지 매니저를 사용해보고, 성능, 설치 방식 등을 직접 비교해 결정하는 건 어떨까!?
다음 글은 pnpm 실습 글을 가져와보겠습니다~!
사용 해 봤던 npm, yarn부터 아직 사용해보지 못했지만 관심 가지고 있었던 yarn berry, pnpm까지! 사례까지 자세히 설명되어 있어서 어려운 내용임에도 이해하기 편했습니다! 읽어보면서 다양한 패키지 매니저의 종류와 특징을 비교해볼수 있어 좋았어요 !!
저는 npm(npx)을 사용하다가, npm이 느리다는 것을 알게 된 후로 yarn을 주로 사용하고 있었는데요, 이번 아티클을 읽으면서 속도 외에도 npm과 yarn의 차이가 무엇인지 더 정확히 알아갑니다!
아티클을 읽고 특히 아직 사용해보지 못한 yarn berry, pnpm에 대해 더 궁금해져서 찾아보다가, pnpm과 yarn berry는 모노레포 환경에서 효과적으로 사용될 수 있는 패키지 매니징 방법이라는 것
을 발견했어요.
함께 알아두면 좋은 내용 같아 댓글로 공유합니다!
모노레포란 버전 관리 시스템에서 두 개 이상의 프로젝트 코드가 동일한 저장소에 저장되는 소프트웨어 개발 전략으로, 여러 프로젝트 간 코드 공유와 재사용이 쉽다는 장점이 있다
고 합니다
실제로 화해, 무신사와 같은 기업에서는 다수의 도메인에서 효율적인 개발을 하기 위해 멀티레포가 아닌 모노레포를 도입한 사례가 있더라구요!
이러한 모노레포의 도입에 하나의 심볼릭 링크로 패키지 의존성을 효율적으로 관리할 수 있는 pnpm을 고려해보면 좋을것 같다는 생각을 했습니다.
꼼꼼한 정리 감사합니다✨!
작은 개념부터 차근차근 설명해 주셔서 세가지 패키지를 이해하는데 정말 도움이 많이 되었습니다!
결국 node-modules를 생성하지 않는 PnP방식을 통한 zero-install이 주요 포인트 중 하나라고 이해 했는데요. npm은 가장 기본, pnpm은 npm의 의존성 문제를 해결, yarn은 npm보다 빠른 설치와 버전 관리, yarn berry는 pnp방식이 특장점이라면, 확실히 pnp방식의 장점을 살리려한다면 yarn berry를 선택하는게 맞을 것 같습니다.
또한 yarn과 pnpm사이에서 비교를 하자면 yarn에서의 호이스팅을 통한 ghost dependency를 막고 공간 절약, 효율적인 의존성 관리가 가능하다는 점에서 장점이 있는 것으로 정리할 수 있겠는데요. yarn berry가 yarn을 보완한 최신 버전이라고 생각한다면, 다른 것이 아닌 yarn을 써야 할 이유가 조금 애매해지는 느낌입니다. 레퍼런스가 많아서? 알아보니 yarn(classic)은 레거시로 여겨지고, yarn 레포에서 1.x 버전의 유지보수를 중단하고 새로운 기능이나 버그 픽스는 Yarn berry에서 이루어 진다고 명시한 걸 보면 yarn berry로의 움직임이 필요하지 않을까하는 생각이 듭니다.
배민에서는 yarn berry를 선택한 이유로 Zero-install을 모노레포에서도 그대로 활용할 수 있었던 건 무시하기 어려운 yarn berry만의 장점
이라고 꼽았더라구요. 또 이런 점에서 모노레포를 구축하기에 가장 어울리는 package manager
라는 말도 있더라구요.
이제 여기서 저는 모노레포
라는 것이 대체 무엇이냐.. 에 대해 궁금증을 안게 되었는데요. 단일 프로젝트만을 다뤄보았기에 생소하게 느껴지는 개념인 것 같습니다. 모노레포는 여러개의 프로젝트를 관리할 때 하나의 레포지토리에 저장하는 전략인데, 모노레포와 반대되는 멀티레포
방식에서는 도메인 별로 레포지토리를 달리하여 독립적인 관리가 가능해집니다. 다만 유기적으로 연결되어있는 도메인들 사이에서 작업물을 서로 공유할 수 없는 물리적인 벽이 생긴다는 점이 문제라고 하네요. 따라서 모노레포
에서는 모듈화를 통해 로직을 재사용하고 프로젝트 사이의 의존성을 더 쉽게 관리할 수 있는 등의 장점이 생깁니다. 이 역시 모노레포가 언제나 좋다라고는 할 수 없기에 프로젝트의 특성에 맞게 전략을 세워야겠네요.
여러 패키지를 너무 알기 쉽게 자세히 설명해주셔서 이해가 쏙쏙 됐어요!!
npm과 yarn만 알고 사용해봤는데, yarn berry와 pnpm이라는 패키지 매니저를 처음 알게 되었어요.
yarn과 npm도 장단점을 모르고 사용만 했었는데, 이제는 각자 장단점을 알고 사용할 수 있을 것 같아요. 특히 yarn이 npm보다 빠르다는 것은 알고 있었는데, 왜 빠른지 이제 알 것 같아요!!!
여러 프로젝트를 동시에 진행할 때 중복된 모듈들을 각 프로젝트에서 사용해서 메모리 낭비가 심하다고 생각했던 저깅 있는데, 이를 해결해쥴 Pnpm이라는 좋은 기술도 있었네요!!!
yarn berry에 대해 조금 더 찾아보다가 모노레포 환경을 구축하는데 효율적인 패키지 매니저라는 내용을 보고, 모노레포라는 개념에 대해 찾아보면서 여러 패키지를 단일 repository에서 관리하는 모노레포 개념에 대해 처음 알게 되었고, 이를 도와주는 lerna라는 툴에 대해서도 처음 알게 되었어요.
Lerna는 단일 Repository에서 다양한 패키지를 구성하는 것을 도와주는 라이브러리로(모노레포), 프로젝트 전체를 빌드하거나, 테스트 할 때 변경이 있는 패키지들을 배포할 때 도움을 준다고 해요!!
yarn과 lerna를 같이 사용하여 모노레포를 구축하는 방법도 있고 yarn berry로 모노레포를 구축하는 방법도 있는데, yarn과 lerna를 사용하는 방법은 레퍼런스가 많지만, lerna를 사용하는 데 진입장벽이 있다는 단점이 있어서 배민에서는 yarn berry를 사용하여 모노레포를 구축했다는 글도 찾아봤어요!! 빌드 속도도 lerna로 구축하는 것보다 몇 배는 빠르다고 해요!
yarn berry의 단점도 궁금해서 찾아봤는데, 패키지 중 PnP를 지원하지 않는 패키지도 존재해서 이런 패키지가 프로젝트에 존재한다면 PnP의 장점을 제대로 누릴 수 없다는 단점도 있다고 해요... 그래서 각 프로젝트의 특성에 맞게 패키지 매니저를 선택하는 것도 고민해보아야 할 일이라고 생각합니다 :)
덕분에 여러 패키지 매니저들의 장단점을 이해하고, 패키지 매니저 선택의 중요성에 대해 알게 되었어요!!! 좋은 아티클 너무너무 감사합니다!!!!!😄😄
패키지 매니징에 관한 좋은 글 잘 읽고 갑니다! 너무 깔끔하게 정리 잘 해주신 것 같아요! 예전에 처음 프론트 엔드 개발을 배우기 시작할 때 npm으로 (다들 npm으로 시작은 하지 않을까용,,?ㅎㅎ) 경험했던 기억이 납니다. 그 당시에는 yarn이 무엇인지도 몰랐고, npm만 알았었는데, 그래서인지 느리다고 생각을 하진 못했어요... 그런데 yarn을 알고 나니까 그동안 꽤 느리고 큰 걸로 노트북을 혹사시키고 있었구나,, 라는 생각도 같이 했던 기억이 납니다!
yarn이 오프라인 상태에서도 설치가 가능하다는 걸 이번에 처음 알 수 있었어요!
저는 프로젝트에서 yarn이랑 npm만 사용해 봤는데, 두 개 차이도 꽤 많이 났다고 느꼈습니다. 그렇기 때문에 다른 패키지 매니저들도 궁금해요ㅎㅎ..
npm은 패키지를 찾지 못할 경우엔 node_modules 폴더를 계속 검색하기 때문에 어떤 node_moduels를 포함하고 있는지에 따라 의존성을 불러 올 수 있는 여부나 다른 버전의 의존성을 불러 올 수 있는 여지도 존재한다고 해요.
그리고 yarn berry가 PnP 전략으로 유령 의존성을 해결했다는 부분을 처음 알게 되었는데 꽤 흥미로웠습니다. 그 외에 yarn berry는 플러그인 친화적인 환경을 자랑한다고 합니다. 그렇기 때문에 플러그인을 손쉽게 만들 수 있다고 합니다. 두번째 yarn berry의 다른 장점으로는 높은 워크 스페이스 기능 제공인데요, TS 환경에서도 한 패키지의 소스 코드의 변경 사항을 즉시 다른 패키지에 반영할 수 있따고 합니다.
마지막으로 yarn berry는 yarn patch 명령어를 제공하여, 쉽게 라이브러리의 일부분을 수정하여 사용할 수 있다고 합니다.
https://toss.tech/article/node-modules-and-yarn-berry
https://blog.hwahae.co.kr/all/tech/11962
npm과 yarn에 대해서는 알고 있었지만 pnpm에 대해서는 몰랐었는데 이번 아티클을 통해 새로 배울 수 있어 좋았습니다!! 언젠가는 정리해야지 하던 주제인 npm vs yarn에 대해서 대신 자세히 정리해주셔서 감사합니다!!
또, package-lock.json의 역할이 궁금해서 찾아봤어요!
짧게 요약하자면 앞서 아티클에 설명되어 있던 npm의 단점 중 2번째, 일관적이지 않은 패키지 버전을 보완해주는 거라고 하네요
여러 개발 환경에서 발생하는 의존성 버전 정보를 고정시키기 위해 사용한다고 합니다
yarn.lock과 같은 역할인 거 같습니다!!
참고자료 https://jihyundev.tistory.com/21
zero-install에 대한 설명을 읽으면서 도대체 설치를 안 했는데 어떻게 사용이 가능한건지에 대해 궁금증이 생겨서 공식문서를 확인해 봤습니다!!
이는 브랜치를 전환할 때 yarn install을 실행하지 않아도 되는 기능이라고 합니다. 이유는 아래와 같습니다
yarn은 패키지 캐시를 프로젝트 내의 로컬 폴더에 저장시켜, npm registry에 대한 의존성을 제거하였습니다. -> offline mirror
PnP loader는 어떤 머신이든 동일한 내용을 가지고 있으며, offline cache는 loader가 참조하는 모든 파일이 포함되어 있으므로, Yarn PnP와 offline mirror를 사용하는 한, Git에 loader 파일을 추가하기만 한다면 git checkout 호출은 곧 yarn install의 역할을 한다고 합니다.
참고자료 https://yarnpkg.com/features/caching
저도 그냥 아무 생각없이 npm 많이 쓰니까 npm 써야지 하다가, 인턴 활동하면서 처음 yarn을 사용하게 되었는데, 훨씬 빠르고 좋은 거 같아서 그 이후론 yarn을 더 선호하게 되었습니다. (로고도 더 귀엽,,) yarn version 3.x 을 쓰면 좀 복잡해진다고(?) 해서 yarn classic 사용하라는 팀장님의 얘기에 저는 일단 classic만 사용했었는데요, 이 글을 보니 yarn berry도 사용을 해보고 싶다는 생각이 들었습니다! 좋은 아티클 잘 읽었습니다 :)
어렴풋이 사용해본 경험이 기억나는건 npm과 yarn인데요, 사실 이 패키지 매니저를 어떤 이유로 사용하고, 어떤 역할을 하는지는 잘 모르고 있었던 것 같아요. 습관처럼 npm start
, npm install i
를 사용하던 제가 떠오르네요.. 또한 node_modules의 개수가 너무 많아서 다운받는데 너무 오래 걸렸던 기억도 있어요..
이번에 아티클을 읽으면서 이 패키지 매니저들이 어떤 일을 하고, 그 장점과 단점에 대해 알 수 있었던 것이 너무 좋았습니다! 특히 npm과 yarn을 비교 분석 해주신게 너무 인상깊었어요! 아직 협업을 제대로 진행해본 적은 없어서 패키지 매니저의 버전이 다를 때 어떤 문제가 생기는지 그 심각성을 모르겠지만 만약에 협업을 진행한다면 yarn berry를 사용하는게 가장 좋을 것 같다는 생각을 해보았습니다! 유령 의존성을 해결하기 위해 PnP방식을 채택했다는 것과, 각 zip파일을 이용해 의존성을 관리한다는 점에서 큰 메리트를 느꼈어요!
왜 이미 널리 사용되고 있는 npm이 있는데 다른 패키지 매니저들이 등장했는지 좀 더 궁금해 찾아보았는데요! 이미 아티클에 나와있는 내용 이외에 더 추가해보자면, npm에는 보안의 문제가 있었다고 합니다. npm은 패키지를 중앙 집중식 저장소인 npm 레지스트리에 등록합니다. 개발자들은 npm 레지스트리에서 패키지를 검색하고 필요한 패키지를 설치할 수 있는데요, npm은 패키지를 설치할 때 레지스트리에서 해당 패키지를 다운로드해 사용자의 프로젝트에 설치하는 방법을 취합니다. 하지만 만약 악성코드를 넣고 패키지를 배포한다면 문제가 발생할 것입니다. 대표적인 피해 사례로는 2015년의 엑스코드 사건을 들 수 있다고 합니다.
그나마 2017년, 패키지의 무결성을 보장하기 위해 package.json과 package-lock.json 파일을 사용해 안정성을 높였다고 해요. 꼭 이것이 다른 패키지 매니저가 생겨난 배경이라 할 순 없겠지만 어느정도 지분은 있었을 것이라 생각해요..
참고 : https://html-jc.tistory.com/676
저같은 경우에는 사실 대규모 프로젝트를 진행하는 것이 아니라면 아직은 가장 큰 커뮤니티를 보유하고, 사용성이 좀 더 좋다고 생각하는 npm을 사용해 프로젝트를 진행할 것 같긴 합니다..ㅎㅎ
아티클을 읽으면서 다양한 패키지 매니저의 종류를 알 수 있었고, 비교를 해볼 수 있어 유익한 시간이였던거 같아요! 좋은 아티클 감사합니다!!
다양한 패키지 매니저에 대해 쉽게 설명해주셔서 이해가 잘 됐습니다!! 전 처음 개발을 시작했을때는 npm, 그리고 그 후에는 yarn이 더 좋고 새로운것이라는 막연한 이유로 yarn 사용을 지향했는데요 , 그래도 npm이 손에 익어서 잘 안고쳐지더라구요 ,, 그랬는데 사실 더 발전시킨 패키지 매니저가 이렇게 많다니 역시 배울게 넘 많아요~~
전 '모노레포'라는 개념을 처음 접해봐서 찾아봤어요! 첨엔 mono repository라는건가? 생각했는데 맞는거같더라구요. 모노레포(monorepo) 구조는 두 개 이상의 프로젝트가 동일한 저장소에 저장되는 소프트웨어 개발 전략이다.
라고 하네요!
아마 본문 중 그리고, 모노레포 내의 패키지들에 얽힌 dependency를 별도로 설치, 관리해야했습니다.
<- 이 말은, 두개 이상의 프로젝트를 하나의 레포지토리에서 관리해야하다보니 생긴 yarn berry의 단점이라고 이해했습니다.
사실 ㅎ,ㅎ npm과 yarn에 대해서 잘 모를땐 한 프로젝트 내에 두 패키지매니저를 모두 동시에 사용해본 적도 있었는데요,, 그럴때 종종 생기는 오류 메세지를 구글링해보면 결론이 'yarn.lock과 package-lock.json간의 충돌
이니까 둘중하나를 지워라!'였어요. 당시에는 이유를 모르고 그냥 삭제하라니까 삭제했는데, 패키지 관리방식이 달라서 충돌이 나는거라 그런거였네요!! 어떨땐 삭제해도 에러 해결이 잘 안된적이 있었는데 아마 그땐 유렁의존성 등 때문이었을거같다고 아티클 읽으며 생각했어요.
그런데 저처럼!! npm과 yarn을 잘 모르고 프로젝트를 시작했다가, 어느정도 플젝을 진행했을때 패키지매니저를 변경하고싶어지면 어쩌지하는 생각을 했습니다. 저만 신기한걸수도 있지만 그냥 해당 패키지 파일을 삭제하고 변경하고싶은 패키지매니저를 설치하면 된다네용 .. 생각보다 간단해서 신기 .. 참고한 글입니닷 https://ahnanne.tistory.com/94
좋은 아티클 감사합니당 ♥
패키지 매니저에 대해 많이 몰랐는데, 아티클을 읽고 공부하면서 yarn과 npm의 차이는 무엇이었는지, 그리고 최근 대두되는 pnpm과 yarn-berry의 차이점들을 한번에 알아볼 수 있어서 너무 유익했어요!
특히, yarn-berry에 대해서는 가장 무지하면서도 지난 심화스터디에서도 주제로 다뤘고, 종종 심화 구현을 하는 분들이 해당 패키지 매니저를 사용하시는걸 보고 어떤 특장점이 있어서 기존 yarn이 아닌 yarn-berry를 사용하는걸까 궁금했는데, PnP라는 개념을 처음 알게되었네요!
경로 설정을 잘못한 채로 yarn 을 실행해서 어마무시한 node_modules 폴더를 깃에 올려보고, file-changed에 세자리수 네자리수가 찍히는 경험을 프론트 개발자라면 누구나 살면서 한번쯤은 해볼 것 같은데요 ㅎ 그런 끔찍한 실수를 방지함과 동시에, 의존성도 함께 git으로 버전관리를 할 수 있는 툴이라는 사실이 정말 큰 강점으로 보입니다! 앞으로 저도 협업 시 yarn-berry를 꼭 한번 경험해보면서 그 특장점을 직접 느껴보고 싶다는 생각이 드네요.
pnpm과 yarn-berry 중 어떤 것이 더 좋을지에 대해서는 아직까지 고민의 영역인 것 같아서, 지나가는 얘기로 pnpm을 적극 추천하셨던 저의 전 직장 프론트팀 팀장님께 호다닥 달려가 질문을 드려보았는데요!!! 답변이 오는대로 후다닥 추가하겠습니당
패키지매니저에 대해 이해하기 쉬운 글을 작성해주셔서 다시 한번 기억을 되짚어가는데 큰 도움을 받았습니다!
저는 yarn-berry 부분을 읽으며 모노레포에도 평소에 관심이 많아 알아보고 싶었는데요
모노레포는 하나의 레포지토리에서 독립적인 여러 프로젝트를 관리하는 것이고
이의 장점은 빠른 코드수정, 중복되는 코드 삭제가능, 코드 컨벤션 통일 (eslint패키지 만들고 각 패키지에 주입)
정도 있습니다. 또한 CI/CD 과정에서도 각각 레퍼지토리를 테스트하는 것이 아니라 yarn test명령어로 한 번에 가능하다고 합니다
하지만 단점으로는 의존성관리 설계부터 많은 노력을 기울여야하며 코드 ownership에 위배될 수 있으며 프로젝트가 무거워질 수 있다는 점들이 있습니다.
모노레포 관리툴은 Lerna, Turborepo 등이 있네요
그 중 Turborepo를 조금 찾아봤는데 eslint커스텀이나 tsconfig 공통 작성 가능하고, nextjs.json설정도 가능하다고 합니다 또 테스트를 위한 스토리북을 하나로 합치거나 UI패키지 폴더(어드민, 유저 등)를 하나로 합치는것이 가능하다고 합니다
사실 너무 잘 작성해주구 리서치해오셔서 오히려 제가 많이 배운 것 같아요..! 감사합니다 😆
저도 playground 개발할 때, yarn pnp를 적용해서 zero install의 이점을 가져가보려 했는데, 말씀해주신대로 지원하지 않는 라이브러리가 하나라도 있을 경우 이게 정상적으로 사용이 어렵더라구요,, 그래서 결국 yarn berry + node_modules (nodeLinker: node_modules
)를 사용하게 되었어요.
한 가지 팁은, pnp를 지원하지 않는 라이브러리들의 경우 직접 의존성들을 yarn 설정파일에 명시해줌으로써 사용할 순 있어요! 하지만 번거로운 작업이기 때문에 자신이 개발하는 프로젝트가 이걸 도입할 만큼의 가치가 있는 프로젝트인지 잘 고민이 필요할 것 같습니당
정리해주신 부분에 더해서, dependency가 무엇이고, devDependency는 또 무엇이며 peerDependency가 무엇인지 잘 비교해서 공부해보면 좋을 것 같아요! resolution도요! 고생하셨습니당
패키지 매니저의 종류 별 특징이 너무 잘 정리되어 있어서, 각각의 패키지 매니저에 대해 제대로 짚고 넘어갈 수 있었어요! 특히, 과거 npm의 단점을 알고나니 어떤 계기로 yarn이 나오게 됐는지, pnpm과 yarn berry는 또 어떤 점을 보완해서 나왔는지에 대해 다시 한 번 생각해볼 수 있었어요!
저는 yarn berry를 시도하려다 제대로 사용해보지 못하고, 결국엔 yarn으로 프로젝트를 마무리했던 경험이 있는데요, 당시 주변에서도
yarn berry를 사용하면 사용할수록 머리 아픈 일이 많이 생길테니 사용을 지양하는게 나을 것 같다!
라는 조언을 해주신 분들이 꽤 있었던 기억이 나네요..!zero-install을 기대하고 yarn berry를 프로젝트에 도입했음에도 종종 yarn install을 했던 경험이 있다는 이야기를 접할 수 있었는데, 그 이유가 궁금해서 여러 자료를 찾아보게 되었어요!
yarn은 현재 v4까지 올라오고 있음에도 여전히 PnP를 지원하지 않는 패키지가 존재하고, 프로젝트 내에 이러한 패키지가 하나라도 존재한다면 PnP 방식이라 하더라도 node_modules가 따라오게 된다
고 하더라구요! 이러한 사실을 알고나니, yarn berry의 큰 장점이라 할 수 있었던 PnP를 제대로 활용하지 못할 수도 있다는 점은 꽤나 치명적이라는 생각이 들었어요! (물론 가장 중요한 것은 프로젝트의 목적과 방향성에 맞게 패키지 매니저를 선택하는 것이겠지만요 ..!!)이번 아티클을 통해 패키지 매니저에 대해 더 깊게 알아볼 수 있었어요! 좋은 아티클 감사합니다 :-)