안녕하세요, 코린이의 코딩 학습기 채니 입니다.
[Node.js 교과서]의 책을 참고하여 포스팅한 개인 공부 내용입니다.
패키지 매니저
npm 알아보기
npm (Node Package Manager)
- 대부분의 자바스크립트 프로그램은 '패키지'라는 이름으로 npm에 등록 되어 있음
- 특정 기능을 하는 패키지가 필요하다면 npm에서 찾아 설치
- npm에 업로드된 노드 모듈을 패키지라고 부름
- 패키지가 다른 패키지를 사용할 수도 있음 (의존 관계)
package.json으로 패키지 관리하기
서비스에 필요한 패키지를 추가하다보면, 관리가 어려워지고 버전별로 기능이 다를 수 있으므로 프로젝트 설치 시 동일한 버전을 사용해야 합니다.
package.json
- 설치한 패키지의 버전을 관리하는 파일
- 노드 프로젝트를 시작하기 전에는 폴더 내부에 반드시 package.json 파일을 생성하고 시작
- npm에서 package.json을 만드는 명령어 제공
package.json 설치 - 콘솔로 프로젝트를 시작할 폴더로 이동
npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (playground-cepark) npmtest
version: (1.0.0) 0.0.1
description: hello package.json
entry point: (helloWorld.js) index.js
test command:
git repository: (https://github.com/codewritz-repo/playground-cepark.git)
keywords:
author: chany
license: (ISC)
About to write to /Users/parkchaeeun/project/playground-cepark/package.json:
{
"name": "npmtest", // 프로젝트 이름 입력
"version": "0.0.1", // 프로젝트 버전 입력
"description": "hello package.json", // 프로젝트 설명 입력
"main": "index.js",
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/codewritz-repo/playground-cepark.git"
},
"author": "chany", // 이름 입력
"license": "ISC",
"bugs": {
"url": "https://github.com/codewritz-repo/playground-cepark/issues"
},
"homepage": "https://github.com/codewritz-repo/playground-cepark#readme"
}
Is this OK? (yes) yes
필요없는 명령어들은 Enter로 넘겼고, 추후 필요하다면 package.json에서 수정하면 됩니다.
- package name
: 패키지의 이름, package.json의 name 속성에 저장 - version
: 패키지 버전 - entry point
: 자바스크립트 실행 파일 진입점, package.json의 main 속성에 저장
: 보통 마지막으로 module.exports 하는 파일 저장 - test command
: 코드를 테스트할 때 입력할 명령어 의미, package.json scripts 속성 안의 test 속성에 저장 - git repository
: 코드를 저장해둔 깃 저장소 주소를 의미, package.json repository 속성에 저장
: 나중에 소스에 문제가 생겼을 때 사용자들이 해당 저장소에 방문에 문제 제기 혹은 코드 수정본을 올릴 수 있음 - keywords
: package.json의 keywords 속성에 저장 - license
: 해당 패키지의 라이선스를 넣음
npm init 명령어가 실행되면 아래와 같은 파일이 생성됩니다.
package.json
{
"name": "npmtest",
"version": "0.0.1",
"description": "hello package.json",
"main": "index.js",
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/codewritz-repo/playground-cepark.git"
},
"author": "chany",
"license": "ISC",
"bugs": {
"url": "https://github.com/codewritz-repo/playground-cepark/issues"
},
"homepage": "https://github.com/codewritz-repo/playground-cepark#readme"
}
scripts 부분은 npm 명령어를 저장하는 부분입니다.
콘솔에서 npm run [스크립트 명령어]를 입력하면 해당 스크립트가 실행됩니다.
@콘솔출력값
$ npm run test
> npmtest@0.0.1 test
> echo "Error: no test specified" && exit 1
Error: no test specified
- Error: no test specified
- 콘솔에 해당 문자열을 출력하라는 뜻
- exit 1
- 에러와 함께 종료하라는 것을 의미
- npmtest@0.0.1
- npmtest 패키지의 0.0.1 버전을 의미
test 스크립트 외에도 scripts 속성에 명령어를 여러 개 등록해두고 사용할 수 있습니다.
보통 start 명령어에 node [파일명]을 저장해두고 npm start로 실행합니다. (start, test 같은 스크립트는 run을 붙이지 않아도 됨)
패키지 설치
package.json이 있는 폴더의 콘솔
$ npm install express
added 57 packages, and audited 58 packages in 676ms
7 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
express 패키지를 설치하였고, 설치한 패키지가 package.json에 기록됩니다.
package.json
{
"name": "npmtest",
"version": "0.0.1",
"description": "hello package.json",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "chany",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
}
}
dependencies 속성이 생성되고, express라는 이름과 함께 설치된 버전이 저장되었습니다.
추가로 node_modules라는 폴더도 생성되었고, 설치한 패키지들이 들어있는 것을 확인할 수 있습니다.
실제론 express 패키지 하나만 설치하였지만, Express가 의존하는 패키지들까지 설치된 것을 확인할 수 있습니다.
패키지 하나가 다른 여러 패키지에 의존하고, 그 패키지들은 또 다른 패키지들에 의존하기 때문입니다.
또한, package-lock.json 파일도 생성되었습니다.
node_modules에 들어있는 패키지들의 정확한 버전과 의존 관계가 담겨있습니다.
npm으로 패키지를 설치, 수정, 삭제할 때마다 패키지들 간의 정확한 내부 의존 관계를 해당 파일에 저장하게 됩니다.
**정리
- package.json
- 직접 설치한 패키지를 기록하는 파일
- package-lock.json
- 패키지 간의 의존 관계를 명시한 파일
모듈 여러 개를 동시에 설치할 때는 npm install [패키지1], [패키지2], [...]와 같이 패키지들을 나열합니다.
@콘솔출력값
$ npm install morgan cookie-parser express-session
Debugger attached.
added 11 packages, and audited 69 packages in 764ms
7 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
package.json
...
"dependencies": {
"cookie-parser": "^1.4.6",
"express": "^4.18.2",
"express-session": "^1.17.3",
"morgan": "^1.10.0"
}
...
실제 배포 시에는 사용되지 않고, 개발 중에만 사용되는 개발용 패키지를 설치할 수도 있습니다.
npm install --save-dev [패키지] [...]로 설치합니다.
@콘솔출력값
$ npm install --save-dev nodemon
Debugger attached.
added 33 packages, and audited 102 packages in 1s
10 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
package.json
...
"devDependencies": {
"nodemon": "^2.0.20"
}
...
dependencies가 아닌 devDependencies 속성이 생성되었고, 개발용 패키지만을 따로 관리해줍니다.
간혹 peerDependencies가 존재하는 경우도 있습니다.
아래와 같이 A라는 라이브러리의 package.json이 다음과 같다고 가정하였을 때
"peerDependencies": {
"jQeury": "^3.0.0"
}
A라는 라이브러리가 jQuery 3 버전을 직접적으로 사용하진 않지만, jQuery 3 버전이 설치되어 있다고 생각하고 코드를 작성했다는 의미입니다.
따라서 A라는 라이브러리를 사용하는 입장에서 jQuery를 미리 설치하지 않았거나, jQuery 3 버전이 아닌 다른 버전을 설치한 경우 에러가 발생하게 됩니다.
peerDependencies와 다른 버전이 설치 되어있다면, ERESOLVE unable to resolve rependency tree에러 메세지가 나타납니다.
- 해결방법
- peerDependencies에 맞게 설치하기
- npm i --force로 강제로 모든 버전 설치 (A는 jQuery 3 버전이고, B는 jQuery 2 버전일 때..)
- npm i --legacy-peer-deps로 peerDependencies 무시
- 애초에 peerDependencies가 서로 충돌하지 않게 패키지 설치하기..^^ (패키지 설치 시 peerDependencies 있는지 확인)
npm 전역(global) 설치
- 패키지를 현재 폴더의 node_modules에 설치하는 것이 아닌 npm이 설치되어 있는 폴더에 설치
- 해당 경로는 보통 시스템 환경 변수에 등록되어 있으므로 전역 설치한 패키지는 콘솔 명령어로 사용 가능
- package.json에 기록되지 않음
- package.json에 기록을 원한다면 npx 명령어 사용
// 맥은 권한 때메 sudo로 설치
// rimraf는 rm -rf 명령어를 윈도에서도 사용할 수 있게 해주는 패키지
$ sudo npm install --global rimraf
Password:
added 12 packages, and audited 13 packages in 343ms
2 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
node_modules 폴더 삭제
$ rimraf node_modules
node_modules 폴더를 지웠기 때문에 package.json과 package-lock.json 만 남아있습니다.
하지만 package.json에 설치한 패키지 내역이 남아있으므로 문제가 되진 않습니다. npm install 한다면 알아서 다시 설치되기 때문이죠.
따라서 node_modules보다 package.json, package-lock.json이 훨씬 중요!!!합니다.
* npm i 를 할 때마다 package.json과 package-lock.json이 변하므로, 실제 서비스를 배포할 때는 npm ci 명령어를 사용하길 권장
패키지 버전 이해하기
노드 패키지는 SemVer 방식의 버전의 넘버링을 이용하므로 항상 세 자리입니다.
SemVer (Semantic Versioning)
- 버전을 구성하는 세 자리가 모두 의미를 가지고 있음
- 각 패키지 간의 의존 관계가 복잡하고, 버전이 다르므로 버전 번호를 어떻게 정하고 올려야 하는지를 명시하는 규칙
- 버전의 첫 번째 자리 - 메이저 버전
- 메이저 버전이 0이면 초기 개발 중이라는 뜻
- 메이저 버전이 1이면 정식 버전이라는 뜻
- 하위 호환이 안 될 정도로 패키지의 내용이 수정되었을 때 주로 올림
- 1.5.0 사용자 → 2.0.0 업데이트 : 에러 발생 확률 ↑
- 버전의 두 번째 자리 - 마이너 버전
- 하위 호환이 되는 기능 업데이트를 할 때 주로 올림
- 1.5.0 사용자 → 1.6.0 업데이트 : 사용 가능
- 버전의 세 번째 자리 - 패치 버전
- 기존 기능에 문제가 있어 수정한 것을 내놓았을 때 주로 사용
새 버전 배포 후 버전 내용을 수정하면 안됩니다.
만일 수정사항이 생긴다면 메이저/마이너/패치 버전 중 하나를 의미에 맞게 올려서 새로운 버전을 배포해야 합니다.
(패키지 간의 의존 관계와 사용자 편리를 위해)
이 외에도 ^ 혹은 ~, >, <와 같은 문자를 볼 수도 있는데, 이는 설치하거나 업데이트할 때 어떤 버전을 설치해야 하는지 알려줍니다.
- ^ 기호
- 마이너 버전까지만 설치하거나 업데이트
- npm i express@^1.1.1 → 1.1.1 이상부터 2.0.0 미만 버전까지 설치 (1.x.x로 표현)
- ~ 기호
- 패치 버전까지만 설치하거나 업데이트
- npm i express@~1.1.1 → 1.1.1 이상부터 1.2.0 미만 버전까지 설치 (1.1.x로 표현)
- >, <, >=, <=, = 기호
- 초과, 미만, 이상, 이하, 동일을 뜻
- npm i express@>1.1.1 → 1.1.1 버전보다 높은 버전 설치
- @latest
- 아전된 최신 버전의 패키지 설치
- npm i express@x 로도 표현
- @next
- 가장 최근 배포판 사용
- 안정되지 않은 알파나 배타 버전의 패키지를 설치할 수 있음
- 알파나 배타 버전
- 1.1.1-alpha.0 나 2.0.0-beta.1 처럼 표시
기타 npm 명령어
- npm outdated
- 업데이트할 수 있는 패키지가 있는지 확인
- npm으로 설치한 패키지 사용 시 새로운 기능이 추가되거나 버그를 고친 새로운 버전이 나올 때가 있음
- Current와 Wanted가 다르다면 업데이트가 필요
- Latest는 해당 패키지의 최신 버전이지만 package.json에 적힌 버전 범위와 다르면 설치하지 않음
- npm update
- 업데이트 가능한 모든 패키지가 Wanted에 적힌 버전으로 업데이트
- npm uninstall [패키지 이름]
- 해당 패키지를 제거
- node_modules 폴더와 package.json에서 사라짐
- npm rm [패키지 이름]으로 줄여쓸 수 있음
- npm search [검색어]
- npm의 패키지 검색
- package.json의 keywords가 사용됨
- npm info [패키지 이름]
- 패키지의 세부 정보를 파악하고자 할 때 사용
- package.json의 내용과 의존 관계, 설치 가능한 버전 정보 등이 표시
- npm login
- npm 로그인을 위한 명령어
- 패키지를 배포할 때 로그인이 필요
- npm whoami
- 로그인한 사용자가 누구인지 알림
- 로그인된 상태가 아니라면 에러 발생
- npm logout
- npm login으로 로그인한 계정을 로그아웃할 때 사용
- npm version [버전]
- package.json의 버전을 올림
- 원하는 숫자를 넣거나 major, minor, patch라는 문자열을 넣어 해당 부분의 숫자를 1 올림
- 예) npm version 5.3.2, npm version minor
- npm deprecate [패키지 이름] [버전] [메시지]
- 해당 패키지를 설치할 때 경고 메시지를 띄우게 함
- 자신의 패키지에만 해당 명령어 사용 가능
- 다른 사용자들이 버그가 있는 버전의 패키지를 설치할 때 경고 메세지 출력
- npm publish
- 자신이 만든 패키지를 배포할 때 사용
- npm unpublish
- 배포한 패키지를 제거할 때 사용
- 24시간 이내에 배포한 패키지만 제거 가능 (의존성 관계 때문)
패키지 배포하기
npm 계정 만들기
- npm 웹 사이트 (https://www.npmjs.com/) 우측 상단의 Sign Up을 통해 회원가입
- 회원 가입 confirm 메일 확인
- npm login 명령어를 입력해 생성한 계정으로 로그인. 이메일 발송된 OTP 코드도 입력해야 로그인됨
index.js
module.exports = () => {
return 'hello package';
}
npm은 패키지 이름이 겹치는 것을 허용하지 않으므로 사용하지 않는 패키지 이름으로 배포해야 합니다.
// 패키지 배포
$ npm publish
- npm info [패키지 이름]
- 해당 패키지 명을 가지고 있는 패키지 정보
해당 명령어로 이름을 사용하고 있는지 확인할 수 있습니다.
정보가 나온다면 누군가가 사용하고 있는 패키지 명이고, npm ERR! code E404 에러가 발생하면 사용 가능합니다.
버전을 올려서 출시해보기
$ npm publish
...
npm ERR! code E403
...
해당 메세지가 나온다면 이미 출시한 버전이라는 의미이고, 버전을 올리기 위해 npm version 명령어를 사용합니다.
$ npm version patch
버전을 올려 배포하는데에 성공하였습니다.
실무에서는 버전을 올려 배포할 때는 release-it이라는 패키지를 주로 사용합니다. (https://github.com/release-it/release-it)
배포한 패키지 삭제해보기
// npm unpublish [패키지 이름] --force
$ npm unpublish npmtest-1234 --force
삭제 후 npm info 명령어를 사용해 404가 뜬다면 정상적으로 지워진 것입니다.
'JavaScript > Node.js' 카테고리의 다른 글
Node) MySQL - 워크벤치 설치하기 (0) | 2022.12.29 |
---|---|
Node) 익스프레스로 웹 서버 만들기 (1) | 2022.12.29 |
Node) http 모듈로 서버 만들기 - 쿠키와 세션, https와 http2, cluster (0) | 2022.12.28 |
Node) http 모듈로 서버 만들기 - 요청과 응답 이해하기, REST와 라우팅 이용하기 (0) | 2022.12.27 |
Node) 노드 기능 알아보기 - 이벤트 이해하기, 예외 처리하기 (0) | 2022.12.27 |