본문 바로가기
프론트엔드/Node.JS

Node.js - 패키지 / packge.json과 package-lock.json / npm /

by 학습하는 청년 2023. 8. 24.

1. package.json이라는 파일을 가진 디렉토리가 패키지다.

- package.json 파일은 해당 패키지에 관한 정보를 갖고 있는 파일.

1) name

- 패키지의 이름

- 특정 패키지를 사용하기 위해 require 함수의 인자로 넣는 것

 

2) version

- 패키지의 버전

 

3) description

- 패키지에 대한 설명

- 패키지를 검색할 때 여기 있는 내용도 검색 기준으로 활용되므로 자신의 패키지가 잘 검색되도록 하려면 설명을 작성하는 것이 좋다.

 

4) keywords

- 패키지에 대한 키워드들

- description과 동일하게 검색 기준으로 활용된다.

 

5) homepage

- 패키지 관련 사이트의 URL

 

6) bugs

- 패키지를 사용하다가 발생하는 버그들을 신고할 수 있는 URL이나 이메일 주소가 적혀 있다.

 

7) license

- 패키지의 라이센스 정보

 

8) author, contributors

- 패키지를 만든 사람과 패키지를 만드는데 기여하는 사람들

 

9) main

- require('패키지 이름') 함수로 로드했을 때, 실제로 로드되는 파일의 이름이 적혀 있는 필드

 

10) man

- 이 패키지의 사용 설명서가 담긴 파일들의 경로

 

11) repository

- 이 패키지의 코드가 관리되고 있는 레포지토리(repository)의 주소

 

12) scripts

- npm으로 간편하게 실행할 수 있는 스크립트 파일들의 정보가 담겨 있다.

"scripts" : {
 "test" : "실행할 커맨드 A"
}

이렇게 작성되어 있다면, 터미널에서 "npm run test"라고 실행하면 '실행할 커맨드 A'가 실행된다.

 

13) dependencies

- 현재 패키지가 의존하고 있는 다른 패키지들이 나열되어 있는 필드

- 이 필드는 Node.js 패키지 생태계의 핵심이 되는 필드

 

13-1) Semantic Version (의미론적 버전)

- dependencies 필등 있는 각 패키지 이름 옆의 버전

- X.Y.Z ex) 1.3.6

X : 메이저 버전(major version)

- 이전 버전의 API와 호환되지 않는(not backward-compatible) API 상의 변화가 발생했을 때 업데이트

- 기존의 API를 아예 삭제했거나 그 이름을 바꾸는 등의 변화가 이것에 해당한다.

- 이럴 때는 2.6.7 버전이었다면 3.0.0으로 버전을 올려줘야 한다.

- 만약 자신이 사용하던 패키지의 메이저 버전이 업데이트되었다면 좋은 소식이 아니다. 최신 버전을 사용하려면, 원래 사용하던 이전 버전 패키지의 API에서 어떤 부분들이 바뀐 건지를 체크하고, 코드를 재수정해야 할 가능성이 높기 때문이다.

- 이런 이유에서, 패키지를 만드는 사람 입장에서도 너무 자주 해서는 안 되는 작업이기도 하다.

 

Y : 마이너 버전(minor version)

- 이전 버전의 API와 호환되는(backward-compatible) API 상의 변화가 발생했을 때 업데이트

- 예를 들어, 2.6.7 버전에서 새로운 API를 추가하면 2.7.0으로 버전을 올린다.

- API 상의 변화가 생기긴 했지만 이미 존재했던 API들은 건드리지 않는 범위의 변화(단순 API 추가)가 발생한 것이기에 새로운 버전을 사용해도 문제없다.

 

Z : 패치 버전(patch version)

- API에 변화를 주지 않는 범위 내에서의 변화가 이루어진 경우에 업데이트

- 겉으로 공개된 API는 바뀌지 않았지만, 코드에 존재하던 버그를 해결하거나, 알고리즘을 바꿔서 그 효율성을 향상시킨 경우 등이 해당된다.

 

13-2) Version Range Syntax 배우기

- Semantic Version을 기반으로 패키지가 다른 패키지의 어느 버전들을 요구하는 지를 나타낼 때 사용된다.

 

A) Basic Syntax

- 부등호만 이해하면 된다.

 

B) Advanced Syntax

- Hyphen Range

 

- X-range : 어느 버전의 패키지여도 상관 없다는 의미

 

- Yilde Range : 

 

- Caret Range : 현재 보이는 가장 왼쪽의 0이 아닌 버전이 바뀌지 않는 선에서의 버전 업데이트만 허용

 

 

2. 하나의 서드 파티 모듈은 하나의 패키지다.

- 패키지는 package.json 파일이 있는 디렉토리이므로 이 디렉토리를 주고받으면 된다. 하지만 패키지를 공유할 때, 패키지 안에 있는 node_modules 디렉토리는 보통 공유하지 않는다. 왜냐하면 보통 패키지를 몇 개만 설치해도 내부 용량이 매우 ㅓ지고, 매번 공유하는 것은 비효율적(용량 문제)이기 때문이다. 그렇다면 의존하는 다른 패키지들이 없으면 정상적으로 실행될 수 없을텐데 어떻게 하면 좋을까? 바로 이때 package.json 파일이 필요하다.

- 패키지를 공유할 때는 그 안의 package.json 파일만 제대로 공유하면 된다. 이 파일의 dependencies 필드에 적힌 '의존 패키지들의 이름'과 'Semantic Version / Version Range Syntax'를 보고 알맞은 패키지들이 자동으로 설치되기 때문이다.

--> 정리하면, 패키지를 공유받는 사람이 npm install 명령어를 실행해서 공유받은 package.json 파일을 기반으로 직접 생성한다.

 

packge.json 파일과 package-lock.json 파일

- package-lock.json 파일 : 맨 처음 패키지를 설치했을 때 생성 / dependences 필드에, 현재 패키지 안에 어떤 패키지들이 설치되어 있는지 그 정보가 담겨 있다. - '현재 패키지에 실제로 성치되어 있는 다른 패키지들의 버전'이 적혀 있는 것

 

- package.json 파일 : npm init 명령어를 사용해서 디렉토리를 하나의 패키지로 만들었을 때 생성 / dependencies 필드에 어떤 패키지들이 설치되어야 하는지에 대한 정보가 담겨 있다. - Version Range Syntax를 만족하는 버전의 패키지라마ㅕㄴ 언제든 업데이트된 버전의 패키지가 설치되어도 괜찮다는 의미. - '현재 패키지가 동작하기 위해 필요한 다른 패키지들의 버전 범위'가 적혀 있는 것 

 

=> package-lock.json 파읠이 'package.json 기반의 패키지 공유 방식'이 바라생시킬 수 있는 문제에 대한 해결책

패키지를 공유할 때, package-lock.json 파일도 package.json 파일과 함께 공유하면

npm install

을 실행하면 npm은 package-lock.jsjon 파일의 dependencies를 보고, 특정 버전의 패키지들을 정확히 동일하게 설치한다. 덕분에 공유받은 사람이나 공유해준 사람 모두 동일한 버전의 dependency들을 설치하게 된다. 덕분에 동일한 node_modules 디렉토리를 갖게 되는 것이다. 굳이 용량이 큰 node_modules 디렉토리를 공유할 필요가 없는 이유인 것이다.

 

다시 정리하자면,

1) 패키키를 공유할 때는 보통 node_modules 디렉토리를 제외한다.

2) 패키지 안의 package.json 파일 내용 중 dependencies 필드의 정보에

3) 공유받는 측에서 node_modules 디렉토리를 재생성(npm install)하는 데 사용된다.

4) 이때 공유해준 사람과 공유받은 사람 모두 node_modules 디렉토리 내부의 차이가 없게 만들려면

5) package-lock.json 파일도 package.json 파일과 함께 공유해줘야 한다.

 

이런 패키지 간의 의존 관계에는 위험성이 뒤따른다.

1) 악성코드 문제

- 패키지들의 보안 검사를 위해 npm 커뮤니티에서 많은 노력을 하고 있지만, 특정 패키지, 그리고 그것이 의존하는 패키지들이 사용해도 괜찮은 것인지에 대한 확인은 궁극적으로 서비스를 만드는 개발자의 몫이다. 모든 패키지를 직접 검사하는 것은 어렵겠지만 악성 코드가 있는 패키지를 설치하지 않으려면, 누구나 아는 패키지들만 골라서 이용하는 것이 좋다.

 

2) 패키지 내 코드의 취약점

- npm 측과 각종 보안 회사들은 어떤 패키지의 어떤 점이 취약하다고 주기적으로 발표를 한다.

a) 현재 작업 중인 패키지 안에서 npm outdataed, npm update 라는 명령어를 자주 실행하자.

- npm outdated : 현재 패키지에 설치된 하위 패키지들 중 버전이 최신이 아닌 것이 무엇인지 보여주는 명령어

- npm update : 현재 자신의 패키지에 설치된 모든 패키지들을 최신으로 업데이트 해주는 명령어

=> 최신 버전의 패키지들을 사용할수록 일반적으로 보안상 더 안전하다.

npm update [패키지명]

- 최신 버전으로 업데이트 하기 전에 별도의 검토가 필요해서 모든 패키지를 최신으로 업데이트 하면 안 되는 경우, 원하는 패키지만 업데이트

 

npm update [패키지명]@[버전]

- 최신보다 약간 이전의 버전을 원할 경우

 

b) npm audit, npm audit fix으로 취약점 점검하기

- npm audit : 현재 설치된 패키지들의 이름과 버전을 보고, 발표된 취약점이 있는 정보들을 출력해준다. 이때 npm install fix라는 명령어를 실행하면, npm이 Version Range Syntax를 준수하면서도, 취약점이 해결된 더 최신 버전의 패키지를 자동으로 설치해 준다. 만약, 해결하지 못하는 경우가 발생한다면, More info에 있는 URLL로 들어가서 필요한 해결 조치를 보고 직접 수행하면 된다.

 

3) 패키지의 가용성(Availability) 문제

- 사용 중이던 패키지가 사라져버리거나 관리되지 않고 방치될 수 있다. 현재, npm 저장소에 한 번 올린 패키지는 72시간이 지나면 함부로 삭제할 수 없도록 되어 있다.

 

 

3. npm

- node package manager의 줄임말

- 서드 파티 모듈을 관리한다.

 

전역 설치(global mode 설치)

- 패키지를 하나의 실행 파일인 것처럼 사용할 수 있다.

- 일반 설치는 node_modules 디렉토리에 설치 되고, 전역 설치는 {prefix}/lib/node_modules 경로에 설치된다. 여기서 prefix는 npm에 관한 여러 기본 설정값 중 하나이다. 이 값은 OS에 따라 다르므로 직접 확인해야 한다.

- 전역 설치한 패키지도 require 함수로 불러와 사용할 수 있다. 하지만 이렇게 되면, require 함수 안의 경로명이 불필요하게 길어지고, 나중에 패키지를 외부로 공유할 때 상대방의 컴퓨터에서는 경로가 달라지는 경우가 발생한다(prefix의 값은 OS마다 다르므로)

- 그래서 코드에서 로드할 목적의 패키지는 굳이 전역 설치를 하지 않는다.

 

 

 

 

댓글