npm 버전 5(v5) 이상부터 도입된 lock.file과 몇 가지 최적화 작업에도 불구하고 근본적으로 less aggressive caching과 네트워크 요청에 의존하기 때문에 yarn보다 더 느립니다.
npm 버전7(v7) 이상부터는 병렬화와 몇 가지 개선 작업으로 속도가 그 전에 비해 훨씬 빨라졌지만 여전히 몇 가지 경우에서 Yarn에 비해 약간 느린 모습을 보여주고 있습니다.
반면 yarn은 빠른 것으로 유명한 만큼, 특히 그들의 deterministic dependency resolution(결정론적 의존성 해결), aggressive caching, 그리고 병렬화 등을 내세우고 있습니다.
결정론적 의존성 파싱?: 일종의 그리디 알고리즘에 기반한 파싱 방법으로 더 많은 문맥 자질을 사용할 수 있고, 근거리 의존관계를 찾는데 강하며, 속도가 빠른 장점을 가지고 있습니다. 하지만 잘못 결정할 경우 오류의 전파가 발생한다는 단점이 있습니다.
yarn은 패키지를 더욱 빠르게 설치할 수 있게 해주며, 특히 더 나은 오프라인 캐시 처리로 인해 반복된 설치에서 굉장한 강점을 보이고 있습니다.
3. Lock File
NPM은 package-lock.json을 사용하여 의존성들을 lock 하여, 같은 버전들이 다른 환경에 걸쳐 설치되도록 보장합니다.
YARN은 yarn.lock을 사용하는데, 이 파일도 package-lock.json과 유사한 기능들을 수행하지만, Yarn의 lock 파일은 더 가독성이 높고 의존성들을 더욱 deterministic하게 처리합니다.
4. Dependency Resolutioned (의존성 처리)
NPM v6 이하 버전에서는 중첩 의존성 구조를 가졌기 때문에 의존성 헬(dependency hell)과 같은 이슈를 초래하는 경우가 많았습니다. NPM v7 이상 버전으로 업그레이드 되고 나서부터는 Yarn의 접근과 유사한 "flat'한 node_modules 구조를 사용하여 그러한 이슈들을 해결할 수 있었습니다.
Yarn은 초기부터 결정적 의존성 처리 시스템을 사용하였는데, 이는 모듈간 충돌과 같은 이슈를 감소시키면서도 설치 과정에 걸친 동일 의존성 트리(dependency tree)를 보장하는 방식을 의미합니다.
5. Offline Mode (오프라인 모드)
NPM은 캐싱 기능을 갖고 있지만, 오프라인 지원이 그렇게 강력하지는 않습니다. NPM v7 이상 버전에서 시작하여 오프라인 지원이 많이 개선되었지만 기본적으로 사용할 수 있지는 않습니다.
Yarn은 패키지가 캐싱되어 있다면 오프라인으로도 설치가 가능하며, 이는 제한된 환경 혹은 인터넷 접근이 불가능한 환경에서 일할 때 더욱 강력한 솔루션이 됩니다.
6. Workspaces Support (워크스페이스 지원)
NPM v7에서 지원되는 워크스페이스 기능이 도입되면서, 유저들로 하여금 더 효율적으로 공유되는 의존성을 갖는 모노레포를 관리할 수 있게 했습니다.
Yarn은 초기 버전 이후로 워크스페이스를 지원해왔고, 현재는 매우 성숙하고 모노레포를 관리하기 위해 널리 사용되고 있습니다.
7. Security (보안)
NPM은 알려진 취약점이 있는지 패키지를 검사하고 보안적 경고를 보여줍니다. 하지만 이를 위해 `npm audit` 명령을 구체적인 리포트와 별개로 실행해주어야 합니다.
Yarn v2+ 이상 버전에서도 NPM과 비슷한 내장 보안 감시 도구를 제공합니다. 두 가지 도구 모두 같은 목적으로 기능을 제공합니다. 물론 Yarn의 보안 검사가 뭔가 더 통합적인 것처럼 느껴질 순 있을 것입니다.
8. CLI 명령어
NPM
패키지 설치: npm install [package-name]
전역 설치: npm install -g [package-name]
Yarn
패키지 설치: yarn add [package-name]
전역 설치: yarn global add [package-name]
9. 확장성과 모노레포 핸들링
모노레포 지원(with workspace)이 NPM v7에 추가되었지만, 여전히 기능이 그렇게 많은 것은 아니며, 큰 규모의 모노레포에서 Yarn에 비해 성능이 그렇게 좋은 것도 아닙니다.
Yarn의 워크스페이스 기능은 오랫동안 모노레포와 대규모 프로젝트 관리를 위해 사용하는 데 인기가 많았으며, 더 확장가능한 솔루션과 관리를 제공합니다.
10. Plun'n'Play(PNP)
NPM은 Plug'n'Play를 자체 지원하지 않습니다.
Yarn2는 PnP를 도입하였는데, 이는 node_modules에 대한 의존을 전체적으로 제거합니다. node_modules 폴더를 만드는 것 대신 속도를 증가시키고 디스크 사용을 감소시키면서 의존성을 직접 해결합니다.
하지만 PnP는 특정 툴들에 대해서 호환성과 관련된 문제가 있긴합니다.
11. 커뮤니티와 생태계
Node.js의 자체 패키지 매니저가 된다는 것부터 NPM은 가장 큰 패키지 생태계를 가질 수밖에 없긴 합니다. 대부분의 튜토리얼들, 공식 문서, 써드파티 통합에서 모두 NPM을 빼고 작성하는 경우는 없을 것입니다.
Yarn은 페이스북(현 Meta)에서 개발한 것으로 꽤 큰 커뮤니티를 가졌음에도 NPM의 생태계를 따라잡기에는 앞서 말했듯 아직은 무리가 있습니다. 하지만 Yarn의 인기는 날이갈수록 증가하고 있으며, 이들이 내세우는 성능과 기능 상의 이점을 무시하기엔 너무 몸집이 커졌습니다.
12. Global Binary Handling (전역 바이너리 핸들링)
NPM은 중앙 디렉터리에 전역 패키지를 설치합니다. 그래서 바이너리를 사용하여 PATH에 이 디렉터리를 반드시 추가해주어야 합니다.
Yarn은 별도의 디렉터리에 전역 패키지를 설치하고 자동으로 그들을 연결시켜줍니다. 이는 전역적으로 설치된 도구로 작업하는 것을 매우 단순화시켜줍니다.
13. Migration(마이그레이션)
Yarn에서 NPM으로 마이그레이션 하는 것은 굉장히 쉽습니다. 그냥 yarn.lock 파일을 삭제하고 `npm install`을 실행하면 됩니다.
그러고 나면 package-lock.json 파일이 생겨날 것입니다.
NPM에서 Yarn으로 마이그레이션 하는 방법은 Yarn을 설치하고 `yarn install`을 실행하면 됩니다.