npm은 Node Package Manager의 약어로, 이름 그대로 노드 패키지 매니저. npm의 대체자로 yarn이 있다. 리액트나 리액트 네이티브 같은 페이스북 진영의 프레임워크를 사용할 때 종종 볼 수 있다.
패키지는 저마다 고유한 버전이 있으므로 기록해둬야 하는데 이러한 버전을 관히라는 파일이 바로 package.json이다. 따라서 노드 프로젝트를 시작하기 전에 폴더 내부에 무조건 package.json부터 만들고 시작해야 한다. package.json은 모르고 자주 썼던 npm init으로 만들 수 있다!
예시로 만든 프로젝트의 이름은 npmtest, 버전은 1.0.0, 설명은 npm test project author는 boram으로 생성.
라이선스
오픈 소스라고 해도 라이선스별로 제한 사항이 있으므로 설치 이전에 반드시 확인해야 한다
- ISC, MIT나 BSD 라이선스를 가진 패키지를 사용할 때는 사용한 패키지와 라이선스만 밝히면 자유럽게 사용할 수 있따.
- 아파치 라이선스 패키지는 사용은 자유롭지만 특허권에 대한 제한이 포함
- GPL 라이선스는 조심. 패키지를 배포 시에 자신의 패키지도 GPL로 배포하고 소스 코드도 오픈해야 한다
이후에 사용할 express를 설치. dependencies라는 속성이 새로 생기고 express라는 이름과 함께 버전이 명시. 추가로 node_modules라는 폴더도 생성. 그 안에 설치한 패키지들이 들어있다. 분명히 Express를 설치했는데도 패키지가 여러개. 왜? Express가 의존하는 패키지들. 패키지 하나가 다른 여러 패키지에 의존하고 그 패키지들은 또 다른 패키지에 의존하며 이렇게 복잡하게 얽혀 잇어 package.json이 필요한 것이다.
package-lock.json 이라는 파일도 생성되었고 직접 서치한 express 외에도 node_modules에 들어 있는 패키지들의 정확한 버전과 의존 관계가 담겨있다. npm으로 패키지를 설치, 수정, 삭제할 때마다 패키지들 간의 내부 의존 관계를 이 파일에 저장한다.
위처럼 모듈 여러 개를 동시에 설치할 수도 있다.
개발용 패키지 설치할 수도 있다. 실제 배포 시에는 사용되지 않고 개발 중에만 사용되는 패키지들. npm install --save-dev [패키지]fh tjfclgksek. --save-dev가 개발용 패키지임을 나타내준다.
그러면 package.json에 새로운 속성이 생긴다. 새로 생긴 요기에는 개발용 패키지들만 따로 관리한다.
npm에는 전역(global) 설치라는 옵션도 존재. 패키지를 현재 폴더의 node_modules에 설치하는 것이 아니라 npm이 설치되어 있는 폴더에 설치한다. 이 폴더의 경로는 보통 시스템 환경 변수에 등록되어 있으므로 전역 설치한 패키지는 콘솔의 명령어로 사용가능. 전역 설치를 했다고 해서 패키지를 모든 곳에서 사용한다는 뜻은 아니며 대부분 명령어로 사용하기 위해 전역 설치한다.
방금 rimraf라는 패키지를 전역 설치했다. 리눅스나 맥의 rm -rf 명령어를 윈도에서도 사용할 수 있게 해주는 패키지. rm -rf는 지정한 파일이나 폴더를 지우는 명령어. 전역 설치했으므로 rimraf 명령어를 콘솔에서 사용가능. 전역 설치한 패키지는 package.json에 기록되지 않는다.
PS C:\coding\TIL\node> rimraf node_modules
rimraf로 node_modules 폴더를 삭제. 현재 폴더 내에는 package.json과 package-lock.json 밖에 없는 상태. 설치한 패키지들을 지웠지만 package.json에 설치한 패키지 내역이 들어 있어서 걱정할 필요 없다! npm install만 하면 알아서 다시 설치가 된다.
즉, node_modules는 언제든지 npm install로 설치할 수 있으므로 node_modules는 보관할 필요가 없으며 깃 같은 버전 관리 프로그램을 사용할 때도 node_modules는 커밋하지 않는다. 중요한 파일은 package.json이다.
npx
전역 설치를 기피하는 개발자도 있다. 전역 설치한 패키지는 package.json에 기록되지 않아 다시 설치할 때 어려움이 따르기 때문. 이러한 경우를 위한 명령어로 npx가 존재. 그러면 패키지를 전역 설치한 것과 같은 효과
명령어 줄여쓰기
npm install 명령어는 npm i 로 줄여 쓸 수 있고 --save-dev 옵션은 -D로, --global 옵션은 -g로 줄여서 써도 된다.
노드 패키지들의 버전은 항상 세 자리로 이뤄졌다. 심지어 노드의 버전도 세 자리. 버전이 세 자리인 이유는 SemVer 방식의 버전 넘버링을 따르기 때문. SemVer는 Semantic Versioning(유의적 버전)의 약어로 버전을 구성하는 세 자리가 모두 의미를 가지고 있다는 뜻.
각각의 패키지는 모두 버전이 다르고 패키지 간의 의존관계도 복잡. 만약 어떤 패키지의 버전을 업그레이드했는데 그것을 사용하는 다른 패키지에서 에러가 발생한다면 문제가 됩니다. 많은 패키지가 서로 얽히다 보면 이 문제는 점점 더 심각해진다. 따라서 버전 번호를 어떻게 정하고 올려야 하는지 명시하는 규칙이 등장! 이것이 바로 SemVer이다.
새 버전을 배포한 후에는 그 버전의 내용을 절대 수정하면 안 된다. 만약 수정 사항이 생기면, major 버전, minor 버전, patch 버전 중 하나를 의미에 맞게 올려서 새로운 버전으로 배포해야 한다. 이렇게 하면 배포된 버전 내용이 바뀌지 않아서 패키지 간 의존 관계에 도움이 된다. 특정 버전이 정상적으로 동작하고 같은 버전을 사요하면 정상적으로 동작할 것이라 믿을 수 있다.
버전의 숫자마다 의미가 부여있으므로 다른 패키지를 사용할 때도 버전만 보고 에러 발생 여부를 가늠할 수 있다. 의존하는 패키지의 major 버전이 업데이트되었다면 기존 코드와 호환되지 않을 확률이 크므로 미리 주의를 기울여야. minor나 patch 버전 업데이트는 비교적 안심하고 버전을 올릴 수 있다.
package.json에는 SemVer식 세 자리 버전 외에도 버전 앞에 ^이나 ~또는 >,< 같은 문자가 붙어 있다. 이 문자는 버전에는 포함되지 않지만 설치하거나 업데이트할 때 어떤 버전을 설치해야 하는지 알린다.
가장 많이 보는 기호는 ^이며 minor버전까지만 설치하거나 업데이트 한다.
npm i express@^1.1.1
위처럼 쓴다면 1.1.1이상부터 1.2.0 미만 버전까지 설치된다. 1.1.x와 같은 표현도 가능하다. ~보다 ^이 많이 사용되는 이유는 minor 버전까지는 하위 호환이 보장된다. 추가적으로 @latest도 사용하는데, 안정된 최신 버전의 패키지를 설치한다. x로도 표현할 수 있다. (예: npm i express@lastest 또는 npm i express@x). @next를 사용하면 가장 최근 배포판을 사용할 수 있다. @latest와 다른 점은 안정되지 않는 알파나 베타 버전의 패키지를 설치할 수 있따.
npm으로 설치한 패키지를 사용하다보면 새로운 기능이 추가되거나 버그를 고친 새로운 버전이 나올 때가 있다. npm outdated 명령어로 업데이트할 수 있는 패키지가 있는지 확인해보면 된다. Current와 Wanted가 다르면 업데이트가 필요한 경우.