레이블이 npm인 게시물을 표시합니다. 모든 게시물 표시
레이블이 npm인 게시물을 표시합니다. 모든 게시물 표시

금요일

npm install이 안 된다고? 원인 파악 없이 --force 치지 마라

npm install 에러 npm ERR! code ERESOLVE node_modules 삭제 후 재설치 npm ci 차이 package-lock.json 충돌 peer dependency 에러

프로젝트 클론하고 npm install 한 번에 되면 그날은 운이 좋은 날이다. 실무에서 이게 한 번에 되는 경우가 얼마나 되냐면, 팀이 클수록, 프로젝트 오래될수록 확률이 줄어든다.

문제는 에러 메시지를 제대로 읽지 않고 npm install --force 또는 npm install --legacy-peer-deps를 무지성으로 치는 경우다. 이러면 당장은 되는 것처럼 보이지만 나중에 런타임에서 이상한 에러로 돌아온다. 진짜 실무자는 에러 메시지를 읽는다.

에러 메시지별 원인과 해결

ERESOLVE: peer dependency 충돌

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: myapp@1.0.0
npm ERR! Found: react@18.2.0
npm ERR!   react@"^18.2.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^17.0.0" from some-library@2.1.0

이 에러는 some-library가 React 17을 요구하는데 프로젝트에는 React 18이 깔려 있다는 뜻이다. npm 7 버전부터 peer dependency를 엄격하게 검사하기 시작해서 이 에러가 갑자기 늘었다.

선택지는 세 가지다.

1. 라이브러리를 업데이트한다 (가장 좋음)

npm install some-library@latest

해당 라이브러리가 최신 버전에서 React 18을 지원하면 끝난다. 이게 제일 먼저 시도해야 할 옵션이다.

2. --legacy-peer-deps 옵션 (차선책)

npm install --legacy-peer-deps

npm 6 시절 방식으로 peer dependency를 그냥 무시하고 설치한다. 대부분의 경우 문제없이 동작하지만, 진짜 비호환 라이브러리가 섞이면 런타임 에러가 난다. 팀 전체가 이 옵션을 공유한다면 .npmrc에 박아두는 게 낫다.

# .npmrc
legacy-peer-deps=true

3. --force는 마지막 수단

npm install --force

--force는 캐시도 무시하고 버전 충돌도 무시하고 그냥 밀어붙인다. 개발 의존성이나 급할 때 쓰는 거고, CI/CD에서 이걸 쓰고 있다면 뭔가 잘못된 거다.

ENOENT: node_modules 꼬임

npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /project/node_modules/.package-lock.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory

node_modules가 중간에 망가진 경우다. 삭제하고 다시 설치하면 된다.

# node_modules 통째로 삭제
rm -rf node_modules package-lock.json

# 클린 설치
npm install

Windows라면:

Remove-Item -Recurse -Force node_modules
Remove-Item package-lock.json
npm install

그냥 node_modules만 지우고 재설치하면 되는데, package-lock.json도 같이 지우는 게 나을 때가 있다. package-lock.json이 실제 package.json과 어긋나 있는 경우에 이 에러가 나기도 해서다. 단, package-lock.json을 지우면 의존성 버전이 최신으로 바뀔 수 있으니 팀 공유 프로젝트에선 조심해야 한다.

EACCES: 권한 문제

npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /usr/local/lib/node_modules
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied

글로벌 설치할 때 자주 나온다. sudo npm install -g로 해결했다면 잠깐은 괜찮지만, 이 방식이 습관되면 나중에 권한 문제가 더 복잡해진다. 올바른 방법은 npm 기본 디렉토리를 사용자 홈으로 옮기는 거다.

# npm 글로벌 디렉토리를 홈 폴더로 변경
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'

# PATH에 추가 (~/.zshrc 또는 ~/.bashrc)
export PATH=~/.npm-global/bin:$PATH

# 적용
source ~/.zshrc

ETIMEDOUT / ECONNRESET: 네트워크 이슈

npm ERR! code ETIMEDOUT
npm ERR! errno ETIMEDOUT
npm ERR! network request to https://registry.npmjs.org/lodash failed

회사 네트워크나 VPN 환경에서 자주 나온다. 몇 가지 확인 포인트:

# npm 레지스트리 확인
npm config get registry

# 회사 사설 레지스트리 쓰고 있다면
npm config set registry https://your-company-registry.com/

# 원복
npm config set registry https://registry.npmjs.org/

# 프록시 환경이면
npm config set proxy http://proxy.company.com:8080
npm config set https-proxy http://proxy.company.com:8080

타임아웃 에러는 단순히 npm 서버 응답이 느린 경우도 있어서 재시도 먼저 해본다. 그래도 계속 나오면 레지스트리 설정 확인.

npm install vs npm ci — 이 차이 모르는 사람 많다

CI/CD 파이프라인에서 npm install을 쓰고 있다면 npm ci로 바꿔라.

구분npm installnpm ci
package-lock.json 없으면새로 생성에러로 중단
버전 범위(^, ~)최신 버전으로 설치 가능lock 파일 버전 그대로
node_modules있으면 그대로 두고 업데이트무조건 지우고 재설치
용도개발 환경CI/CD, 배포

npm installpackage.json의 버전 범위 안에서 최신 버전을 가져올 수 있다. "react": "^18.0.0"이면 18.x 최신을 잡는다는 얘기다. CI에서 이걸 쓰면 빌드할 때마다 버전이 달라질 수 있다. npm cipackage-lock.json에 적힌 정확한 버전만 설치한다. 재현 가능한 빌드를 원한다면 CI에서 npm ci가 맞다.

자주 보는 실수 모음

package-lock.json을 .gitignore에 넣는 경우

가끔 이렇게 된 프로젝트가 있다. package-lock.json은 반드시 커밋해야 한다. 이게 없으면 팀원마다 설치되는 패키지 버전이 달라지고, "내 로컬에선 되는데 왜 CI가 터지냐"는 상황이 만들어진다.

npm 버전이 팀마다 다른 경우

프로젝트 루트에 .nvmrcpackage.jsonengines 필드로 버전 명시해두는 습관을 들이자.

{
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=9.0.0"
  }
}

yarn/pnpm 섞어쓰기

package-lock.json(npm), yarn.lock(yarn), pnpm-lock.yaml(pnpm)이 동시에 존재하는 프로젝트가 있다. 이 상태로 팀에서 사람마다 다른 패키지 매니저 쓰면 lock 파일 충돌 지옥이 된다. package.jsonpackageManager 필드로 통일해두자.

{
  "packageManager": "npm@10.2.0"
}

정리

npm 에러는 대부분 세 가지 중 하나다: peer dependency 충돌, node_modules 꼬임, 네트워크/권한 문제. 에러 메시지 첫 줄에 나오는 code를 읽으면 원인이 나온다. --force는 진짜 마지막 수단이고, CI에선 npm ci 써라.