npm ci란?
이슈를 마주쳤을 때, 구글링을 하다보면
가끔 npm ci를 사용하라는 솔루션을 만나고는 했다.
오늘은 npm ci에 대해 좀 더 알아보자.
ci의 의미는 무엇인가요?
npm ci에서 ci는 보통 clean install의 의미로 설명된다.
이름처럼 기존 node_modules를 지우고 lock 파일을 기준으로 깨끗하게 의존성을 다시 설치한다.
언제 주로 사용하나요?
npm ci는 여러 환경에서 같은 결과를 반복해서 만들어야 할 때 잘 맞는다.
- CI에서 테스트를 실행할 때
- 배포 환경에서 의존성을 설치할 때
- lock 파일 기준으로 재현 가능한 설치가 필요할 때
- 로컬 의존성 상태를 한번 깨끗하게 맞추고 싶을 때
핵심은 package.json의 범위를 다시 해석하기보다는 lock 파일에 기록된 의존성 트리를 그대로 설치한다는 점이다.
npm install과 다른 점은?
package-lock.json이 필요하다.
npm ci는 package-lock.json이나 npm-shrinkwrap.json 같은 lock 파일이 있어야 사용할 수 있다.
lock 파일이 없다면 npm install처럼 새 lock 파일을 만들어주는 대신 오류로 종료된다.
package.json과 lock 파일이 맞아야 한다.
package.json의 의존성 선언과 lock 파일의 내용이 맞지 않으면 npm ci는 lock 파일을 고치지 않는다.
대신 오류를 내고 종료한다.
이 차이가 CI 환경에서 중요하다.
개발자가 의존성을 바꾸고 lock 파일을 커밋하지 않았다면 CI에서 바로 실패하므로, 배포 전에 의존성 상태가 어긋난 것을 알 수 있다.
node_modules를 먼저 지운다.
node_modules 폴더가 이미 있다면 npm ci는 설치 전에 해당 폴더를 제거한다.
그래서 이전 설치 결과나 로컬에서 꼬인 의존성의 영향을 덜 받는다.
package.json과 lock 파일을 수정하지 않는다.
npm install은 상황에 따라 package-lock.json을 갱신할 수 있다.
반면 npm ci는 프로젝트의 package.json과 lock 파일을 수정하지 않는다.
.npmrc 플래그를 맞춰야 하는 경우
lock 파일을 만들 때 legacy-peer-deps, install-links처럼 의존성 트리 모양에 영향을 주는 옵션을 사용했다면, npm ci를 실행할 때도 같은 옵션을 사용해야 한다.
이런 옵션을 매번 명령어에 붙이기보다는 프로젝트의 .npmrc에 저장하고 함께 커밋하는 편이 좋다.
legacy-peer-deps=true그렇지 않으면 로컬에서 만든 lock 파일은 멀쩡해 보이는데 CI의 npm ci에서만 설치가 실패하는 상황을 만날 수 있다.
정리
npm install은 의존성을 추가하거나 lock 파일을 갱신할 때 사용하고,npm ci는 이미 확정된 lock 파일을 기준으로 빠르고 재현 가능하게 설치할 때 사용한다고 생각하면 된다.
참고 자료












