본문 바로가기
Search/Package Manager

Javascript Package Manager

by egas 2021. 8. 11.

Package Manager는 패키지를 설치, 업데이트, 수정, 삭제하는 작업을 편리하고 안전하게 수행하기 위해 사용되는 툴이다.

 

Package vs Library

  • 라이브러리: 코드의 작성을 위해 사용되는 코드의 묶음
  • 패키지: 코드의 배포를 위해 사용되는 코드의 묶음

패키지는 라이브러리를 포함할 수 있으며, 일반적으로 라이브러리나 실행 파일을 포함한다. 

 

패키지에는 보통 아래 3가지 정보들이 들어있다.

  • 컴파일한 소프트웨어의 바이너리(binary)
  • 환경 설정(configuration)에 관련된 정보
  • 의존(dependency)에 관련된 정보

Software repository

패키지를 저장하고 관리하는 저장소를 Software repository라고 한다. 패키지를 커뮤니티에 등록하여, 다른 사람들과 공유할 수 있다.

 

각각 언어마다 고유의 Package Manager와 Software repository가 존재한다.

 

  • Python
    • Package manager: pip
    • Software repository: PyPI
  • PHP
    • Package manager: Composer
    • Software repository: Packagist
  • NodeJS
    • Package manager: Npm, Yarn
    • Software repository: Npm, Yarn
  • Java
    • Package manager: Maven, Gradle
    • Software repository: Maven

Javascript의 패키지 매니저인 Npm과 Yarn에 대해 알아보자.

NPM

NPM은 Node Pacackage Manager이다. NPM은 Node.js 설치 시에 기본으로 제공된다. 따라서 많은 사람들이 사용하고 있다. NPM은 세계 최대 규모의 패키지들을 보유하고 있으며, 이러한 패키지들은 노드의 생태계를 더욱 견고하게 만들었다.

 

--save vs --save-dev

--save 옵션으로 설치한 디펜던시는 --production 빌드시 포함된다.

--save-dev 옵션으로 설치한 디펜던시는 --production 빌드시 포함되지 않는다.

 

package.json 파일이란?

package.json은 프로젝트의 mainfest file이다. 프로젝트 정보와 의존성(dependencies) 관리가 가능하다. package.json 문서는 어느 곳에서든 동일한 개발 환경을 구축할 수 있게 해 준다.

 

manifest file: 컴퓨팅에서 집합의 일부 또는 논리 정연한 단위인 파일들의 그룹을 위한 메타데이터를 포함하는 파일

 

package.json으로 충분한 것 같은데 package-lock.json 은 왜 필요한가요?

node modules를 설치하기 위해 npm 5부터 package-lock.json이 생겼다. 동일한 함수 package.json는 node_modules에 대해 언제든지 똑같은 트리를 생성해야 한다. 일부 경우에서는 사실이지만, 다른 많은 경우 npm은 package.json 만으로는 언제든지 똑같은 트리를 생성할 수 없다. 세부 내용은 링크 참고.

 

아래 예시에서 @typescript-eslint/experimental-utils과 @typescript-eslint/parser는 같은 @typescript-eslint/typescript-estree를 dependency로 가지고 있지만 각각 다른 버전을 사용한다.

//package-lock.json 
...
"@typescript-eslint/experimental-utils@^3.10.1":
  version "3.10.1"
  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686"
  integrity sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==
  dependencies:
    "@types/json-schema" "^7.0.3"
    "@typescript-eslint/types" "3.10.1"
    "@typescript-eslint/typescript-estree" "3.10.1"
    eslint-scope "^5.0.0"
    eslint-utils "^2.0.0"

"@typescript-eslint/parser@^4.27.0", "@typescript-eslint/parser@^4.5.0":
  version "4.28.3"
  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.3.tgz#95f1d475c08268edffdcb2779993c488b6434b44"
  integrity sha512-ZyWEn34bJexn/JNYvLQab0Mo5e+qqQNhknxmc8azgNd4XqspVYR5oHq9O11fLwdZMRcj4by15ghSlIEq+H5ltQ==
  dependencies:
    "@typescript-eslint/scope-manager" "4.28.3"
    "@typescript-eslint/types" "4.28.3"
    "@typescript-eslint/typescript-estree" "4.28.3"
    debug "^4.3.1"
    ...

 

NPM Version

https://medium.com/beginners-guide-to-mobile-web-development/introduction-to-npm-and-basic-npm-commands-18aa16f69f6b

모든 패키지에는 major, minor, patch가 존재한다.

// package.json
...
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "4.0.3"
  }
...

 

  • major: 기존 코드를 깨뜨릴 만큼 큰 변화가 업데이트됐을 때 
  • minor: 기존 코드를 손상시키지 않는 모든 새로운 기능에 대해 사용
  • patch: 버그를 수정했을 때 사용

다운로드한 패키지 숫자 앞에는 ~와 ^가 추가적으로 존재할 수 있다.

  • 틸트(~): 현재 지정한 버전의 마지막 자리 내의 범위에서만 자동으로 업데이트한다. (ex. ~1.2.3은 1.2.3부터 1.3.0 미만까지를 포함한다.)
  • 캐럿(^): 1.x.x내에서는 하위 호환성이 보장되므로 그 내에서는 모두 업데이트하겠다는 의미이다. (ex. ^1.2.3은 1.2.3부터 2.0.0 미만 까지를 포함 한다.)
    • 단, 캐럿(^)을 사용할 때 0.x.x에서는 틸드처럼 동작해서 지정한 버전 자릿수 내에서만 업데이트한다.

https://twitter.com/tjholowaychuk/status/429038439778889728?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E429038439778889728%7Ctwgr%5E%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fblog.outsider.ne.kr%2F1041

 

원래 React는 ~(틸트)로 버전 관리를 진행했었지만, 이는 마이너 버전을 바꾸기 때문에 하위 호환성이 지켜지지 않아 에러가 날 수 있다. 때문에 현재는 ^(캐럿)로 진행하여, 마이너 버전을 업데이트하지 않고 패치 버전만 업데이트한다.

YARN

Yarn은 프로젝트의 의존성을 관리하는 JavaScript의 패키지 매니저이다. Facebook이 점차 거대해지는 프로젝트에서 npm을 사용하면서 일관적, 보안, 특히 성능에 대한 문제를 겪게 되었고 npm을 대체할 새로운 패키지 매니저를 개발했다. (하지만, 최근에 npm도 성능이 엄청 많이 향상되었다고 한다.)

 

NPM vs. Yarn: Which Package Manager Should You Choose?

 

Yarn은 모든 패키지를 유저 디렉터리에 저장해 캐싱한다.

-g option을 붙이면 전역으로 설치할 수 있으며 yarn global list 명령어로 리스트를 yarn global bin으로 바이너리 스크립트를 볼 수 있다.

 

  • yarn init : package.json 파일 생성
    • yarn add lodash: 기본 패키지 설치
    • yarn add --dev eslint: devDependencies에 eslint 패키지 추가
    • yarn add lodash@1.2.3: 특정 버전 패키지 설치
    • yarn add lodash@https://github.com/lodash/lodash: github url로 설치
  • yarn install / yarn: 로컬의 node_modules 폴더에 의존 패키지를 설치하거나 업데이트
  • yarn install --force: 강제로 모든 패키지 다시 다운로드
  • yarn install --frozen-lockfile: yarn.lock과 package.json이 동기화되지 않은 상태에서 업데이트가 필요한 경우에는 설치를 실패하고 yarn.lock을 생성하지 않는다.
  • yarn bin [name]: binary script 경로 출력
  • yarn upgrade: 모든 의존 패키지를 package.json에 정의한 버전의 범위에서 업데이트하거나 삭제
    • yarn.lock 파일 재생성
    • package.json은 불변
    • 대규모의 프로젝트에서는 의존된 모든 패키지가 호환성을 보장하기 힘들기 때문에 이 명령을 통해 일괄적으로 패키지를 업데이트하는 것은 좋지 않다
    • yarn upgrade eslint@^4.0.0와 같이 하나씩 지정해 업데이트하는 것을 추천
  • yarn remove eslint: eslint 패키지를 프로젝트에서 제거
    • package.json에서 제거
    • yarn.lock에서 제거
  • yarn check: 현재의 package.json이yarn.lock과 일치하는지 확인

package.json scripts

특정 상황에서만 발생하는 몇 가지 특별한 Life Cycle Scripts가 있다. (prepare, prepublish, prepublishOnly, prepack, postpack etc...)

 

compress 명령 실행 전, 후에 명령을 실행시키고 싶다면 아래와 같이 'pre, post'를 붙여서 가능하게 할 수 있다.

{
  "scripts" : { 
    "precompress" : "{{`compress` 스크립트 이전에 실행}}" , 
    "compress" : "{{파일을 압축하는 명령 실행}}" , 
    "postcompress" : "{{`compress` 스크립트 후에 실행}}" 
  }
}

 

NPM vs YARN

2020년 10월에 npm의 가장 최근 major 변경인 v7 로이 업데이트가 되었다. (링크) npm의 상위 호환으로 yarn을 만들었지만, npm 역시 지속적인 발전으로 인해서 이 둘의 차이는 거의 없어졌다.

 

Sponsor

NPM은 현재 Github(마이크로소프트) 소유이다. (로드맵 링크)

Yarn의 경우 여러 스폰서들이 존재한다. yarn의 다음 로드맵은 yarn berry이다. (yarn berry)

 

Parallel installation of packages

yarn의 경우 package들을 병렬 설치해서 npm보다 속도 측면에서 이점이 있었지만, 이마저도 최근에 npm v5에서부터는 거의 차이가 없을 정도로 좁혀졌다.

npm
yarn

보안성(Security)

 

원래 npm은 패키지가 설치될 때 자동으로 코드와 의존성을 실행할 수 있도록 허용했다. 이 특징은 편리하나 안정성의 위험도가 증가했다. 따라서 yarn 은 yarn.lock을 만들어서 모든 디바이스에 같은 패키지를 설치하는 것을 보장하는 방식으로 개발되었다. 하지만, 현재 npm도 package-lock.json을 제공한다.

 

명령어(Command)

yarn은 npm으로부터 파생되었으므로 기본적으로 비슷한 기능들이 많다. 

https://www.digitalocean.com/community/tutorials/nodejs-npm-yarn-cheatsheet

아래 명령어들에 대해서는 yarn이 npm 명령어를 그대로 수용하기로 결정한 명령어들이다.

https://www.digitalocean.com/community/tutorials/nodejs-npm-yarn-cheatsheet

공간 차지

Yarn stores every package in a global cache in your user directory on the file system.

 

Yarn은 모든 패키지를 파일 시스템의 사용자 디렉터리에 있는 전역 캐시에 저장한다. 따라서 yarn의 경우에는 npm과 비교해서 유일한 단점을 뽑자면 공간을 많이 차지할 수 있다는 점이다.

 

TL;DR

과거에는 확실하게 속도, 보안 측면에서 yarn이 npm보다 앞섰다. 하지만, 현재 yarn과 npm은 차이가 불분명할 정도로 어느 것을 선택하더라도 큰 문제없을 수준까지 도달했다.

 

이에 yarn은 한번 더 도약을 했다. yarn berry에 대해 알아보자.

 

Yarn Berry

Yarn Berry 너는 무엇이야? “Berry” is the codename for the Yarn 2 release line. yarn Berry는 yarn 패키지 매니저의 2번째 새로운 버전이다. 2018년 9월 yarn의 RFC 저장소에 해당 PR로부터 시작..

egas.tistory.com

https://github.com/yarnpkg/berry

 

GitHub - yarnpkg/berry: 📦🐈 Active development trunk for Yarn ⚒

📦🐈 Active development trunk for Yarn ⚒. Contribute to yarnpkg/berry development by creating an account on GitHub.

github.com

 

참고

https://github.com/transcendence42/javascript-archive/discussions/16

 

[JS 스터디] npm · Discussion #16 · transcendence42/javascript-archive

주제 키워드는 자바스크립트의 패키지 관리자인 ✨npm✨ 입니다. npm을 사용해 많은 일들을 할 수 있습니다. 같이 알아보아요! ☘️ 하위 주제 키워드 package.json yarn package-lock.json yarn-lock.json npm scri

github.com

 

728x90

'Search > Package Manager' 카테고리의 다른 글

Yarn Berry  (0) 2021.08.11

댓글