npm package

zmin·2022년 8월 14일
0

https://docs.npmjs.com/


Node Package Manager ; Software Registry (the world largest..)

이름이 그렇듯이 노드 기반으로 작동하기 때문에 노드도 설치해야하는데 nvm 이용해서 설치하기를 권장하네요
왜냐면 그냥 노드 인스톨러는 내부적으로 npm을 설치하는데 이 권한이 로컬 권한이라 전역 권한으로 사용할 때 오류날 수도 있어서 그렇다네요

노드 모듈 뿐만 아니라 노드모듈을 포함하는 패키지들도 있음

package에 대한 정보는 해당 패키지 내부의 package.json에 기록됨(그래서 패키지마다 꼭 필요)
얘를 포함해서 압축하고 걔를 npm registry에 게시하고 이름@버전 의 형태로 나타냄, 버전 없이 이름만 쓰면 latest

실제로 지금 만들고 있는 board만 봐도 node_modules/ 안에 package.json이 많음 → 각 패키지마다 있음!!! 왜냐면 해당 패키지를 설명해줘야하니까

근데 그러면 루트에 package.json이 있는 나의 리액트앱도 일종의 패키지라고 볼 수 있을 것 같다.

그런 모듈들은 node_modules/ 안에 설치가 되고 require() 로 불러올 수 있다 → 자바스크립트 파일이거나 package.json을 포함하는 폴더거나 둘 중 하나의 형태여야함

위와같은 이유로 모듈 ≠ 패키지 모든 모듈이 패키지는 아니고 저 json을 포함하는 경우에만 패키지라고 부름

scope도 지정할 수 있는데 이는 private package를 구성하도록 도와준다. unscoped → public, private → scoped

일단 내 리액트앱 패키지 파일을 한 번 봐보면 depth1의 key들은 다음과 같다

name, type, version, private, dependencies, script, browserslist, devDependencies

여기서 정말 필수적인 것은 두 개

  • name: 패키지 이름, 소문자,-,_ 만 사용
  • version: semantic versioning rule을 따르는 버전 표기

npm init 로 해당 폴더를 패키지로 만들겠다는 선언을 할 수 있고 이러면 package.json 파일을 만들어 낼 수 있음, 질문 형식에 답하면서 구성할 수 있도록 도와주는데 뭔가 나만의 package.json을 구성하는 규칙이 있다면 ~/.npm-init.js 를 통해 커스텀 가능

다른 app에서 사용할 수 있는 모듈을 이제 만들어야하는데 이는 exports object를 이용하여 export할 수 있다.

exports.printMsg = function() {
  console.log("This is a message from the demo package");
}
// 이제 이게 아주 많고 체계적이고 하나가 아니라 여러 개이고 객체로 묶이고 등등..

npm publish를 이용해서 배포 가능

내가 패키지 또는 프로젝트가 의존하고 있는 패키지들은 dependencies와 devDependecies를 통해 열거

→ 이후 패키지 폴더(node_modules)를 통으로 공유하지 않고 이 package.json 을 통해 공유하고 이를 참조하여 npm install함

  • dependencies: production 용
  • devDependecies: 오직 개발환경/테스팅 에만 필요한 패키지

똑같은 패키지라면 둘다 설치할 필요는 없을 것. 하지만 버전을 다르게 하여 테스트하고싶다거나 하면 로컬실행에서 devDependecies로 테스트 해볼 수 있다.

sementic versioning

<major>.<minor>.<patch>

  • major: 이전 버전과 완전 달라지는 부분이 있어 호환성이 떨어지는 버전 체인지(나쁘다는 것이 아님), 말그대로 큰게 바뀌었을 때..
  • minor: 이전 버전과 여전히 호환되지만 새로운 기능을 추가한 경우
  • patch: 버그 고치기

npm semver calculator

  • ^ : major를 변화시키지 않는 모든 버전을 포함 → npm install시에는 그 중 최신버전으로
    • 보통 1.0.0에서 시작하니까 크게 발생하지 않는 규칙일 수도 있는데 정확히는 왼쪽에서 부터 값을 읽을 때 처음으로 0이 아닌 값을 고정시키고 변화시킨다는 것
      ^0.1.2 은 0.1.(은 고정하고 patch만 바꿈)
      ^0.0.3 은 고정하겠다는 의미(바꿀 수 있는 버전이 없음)
  • ~ : minor 범위까지 유지한 채 더 상위 버전으로 사용하겠다 → patch 변화
    • minor 버전이 지정되어있지 않다면 (~1) minor버전도 변화시킬 수 있음
  • >, >=, <, <= : 해당 연산자 오른쪽에 명시된 버전보다 높은/높거나같은/낮은/낮거나 같은 버전
  • - : 양쪽에 명시된 버전 사이의 버전
  • || : 양쪽의 명시된 버전 중 하나
  • -rc : alpha, beta 같이 pre-release된 버전 명시
  • x : 모든 버전이 들어갈 수 있음. 1.2.x 같은 형태로 사용

audit reports

해당 버전의 패키지가 dependency하고있는 패키지들이 vulnerability한지 아닌지 알려주는 것. 문제가 생길 가능성이 있는지 알려줌

→ package.json과 package-lock.json 둘 다 있어야함

fix를 할 때 조심해야하는게 호환성 같은 것들이 같이 변경될 수도 있기 때문에 조심해야함 semver warning으로 알려줌

이런 의존성 취약점 관리를 직접 확인하며 수정할 수도 있겠지만 github dependabot에게 도움받을 수 있음


Q. 버전이 다른 같은 패키지의 경우 어떻게 처리하나?

https://npm.github.io/how-npm-works-docs/npm3/duplication.html

일단 node_module/ 폴더를 보면 package.json에 명시된 패키지들 보다 더 많은 패키지들이 설치되어 있는 것을 알 수 있는데
이는 npm 이 종속성 패키지들을 설치하는 방식때문이다. 일반적으로 종속성 패키지들은 해당 패키지의 node_modules/속에 다시 설치되는 것이 아니라 전부 끌어올려져서 root/node_modules/ 속에 flat하게 설치된다.

그래서 만약 같은 버전의 종속성을 가진다면 추가로 내부에 설치하지 않고 해당 패키지를 공유하여 사용한다.
하지만 버전이 다르다면 추가로 해당 버전을 최상위에 설치할 수 없으므로 패키지 내부의 node_modules/ 에 따로 설치한다.

이것들이 업데이트 될 때도 만약 최상위에 설치된 버전의 모듈을 종속성으로 참조하는 패키지가 있다면 아예 새로 패키지를 설치한다. 만약 참조하는 모듈이 없다면 다시 최상위로 이동시켜 설치하게 된다.

Q. package-lock.json

package.json에 종속성이 다 표시되어있고,
해당 패키지 속의 package.json에 또 해당 패키지의 종속성이 다 표시되어 있을텐데 package-lock.json이 왜 필요한걸까?

그냥 단순히 말하면 package.json은 자세한 정보가 부족하고 생각보다 버전에 대해 관용적이다.
그냥 npm install <package name>을 해봤다면 알겠지만 위에서 말한 semver calculator가 붙여져서 나오는 경우가 많고 버전을 지정해주게 되면 마이너 릴리즈나 버그 패치가 나왔을 때 일일히 또 수정해주는 것이 번거로워 해당 calculator들을 지우지 않고 유지하는 것이 일반적이다.

하지만 그런 작은 변화들이 오류를 불러올 때가 많고 내가 개발했던 환경과 점점 차이가 나게되면 그 사이에서 또 오류가 발생하게 될 것이다.

그니까 개발환경을 완벽하게 동일하게 만들어 주는 파일

npm install 할 때!! 그 시점에 설치된 패키지들의 정보로 업데이트된다. 만약 이 package-lock.json을 토대로 패키지를 설치하고 싶다면 npm ci를 해주어야한다.

Q. 어쨌든 설치된 패키지들의 package.json을 재귀적으로 확인하면 되지 않나?

물론 위에서 말한 ^, ~ 등의 이유도 있고,
그 재귀적인 작업이 생각보다 번거롭다.

  • package-lock.json 하나만 있으면 재귀적으로 package.json을 읽어나갈 필요도 없고,
  • 다른 패키지에서 같은 의존 패키지를 사용했을 때, 그래서 이미 설치된 패키지에 대해 반복적으로 메타데이터를 비교하는 번거로운 작업또한 필요없다.
  • 또한 의존성의 의존성들을 내가 관리할 수 없게 된다.

https://docs.npmjs.com/cli/v6/configuring-npm/package-locks

profile
308 Permanent Redirect

0개의 댓글