증상
- 배포 시 자동 스크립트에서
npm ci실행 도중 다음과 같은 메시지 발생:
npm cican only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. npm ci가 실패해 의존성이 설치되지 않고, 이후 애플리케이션 시작 시 Node가@discordjs/voice모듈을 찾지 못해ERR_MODULE_NOT_FOUND오류 발생.- 로그에
Missing: @discordjs/voice@... from lock file같은 항목이 보임.
원인
npm ci는package-lock.json에 명시된 정확한 상태를 재현하기 위해 사용된다.package.json을 변경한 뒤package-lock.json을 갱신하지 않으면 동기화되지 않아 설치를 중단한다.package.json에 새로 추가한 패키지(@discordjs/voice등)가 lock 파일에 반영되지 않으면npm ci는 보안/일관성 이유로 설치를 거부한다.- 그 결과 호스팅 환경에서는 의존성이 전혀 설치되지 않아
require/import시 모듈 없음 오류가 발생한다.
해결 방법
1단계: 호스팅에서 빠르게 동작시키기 (임시/간편)
호스팅의 시작 스크립트에서 npm ci를 npm install로 변경하면 의존성 설치가 진행되어 즉시 서비스가 작동한다. 단, 재현성(reproducibility)은 떨어진다.
예시 변경 전/후:
# 변경 전 (문제 발생)
if [ -d .git ] && [ "${AUTO_UPDATE}" == "1" ]; then git pull origin ${BRANCH} && npm ci --omit=dev --no-audit --no-fund --foreground-scripts; fi; npm run start
# 변경 후 (임시 해결)
if [ -d .git ] && [ "${AUTO_UPDATE}" == "1" ]; then git pull origin ${BRANCH} && npm install --omit=dev --no-audit --no-fund --foreground-scripts; fi; npm run start
- 사용 이유:
npm install은package.json기반으로 lockfile을 갱신하거나 필요한 패키지를 설치한다. - 주의: 장기적으로는 lock 파일을 정확히 관리하는 것이 안전하다.
2단계: 올바르게 고치기 (권장)
로컬 개발 환경에서 package-lock.json을 갱신한 뒤 커밋/업로드하여 호스팅 환경에서 npm ci가 정상 동작하도록 만든다.
절차:
- 저장소를 로컬로 클론 또는 프로젝트 폴더로 이동
git clone <repo-url>
cd <repo>
- 의존성 설치 및 lock 파일 갱신
npm install
# 필요 시: rm -rf node_modules package-lock.json && npm install
- 설치 확인
npm ls @discordjs/voice
- 변경된
package-lock.json을 커밋하여 원격에 푸시
git add package-lock.json
git commit -m "Update package-lock to include @discordjs/voice"
git push
- 호스팅에서 자동 배포가 트리거되면
npm ci가 lock 파일과 동기화된 상태로 의존성을 정확히 설치함.
- 호스팅 패널에서 Git 접근 권한이 없으면 로컬에서 생성한
package-lock.json을 파일 업로드(또는 패널의 파일 편집기)로 올리면 된다.
추가 팁:
- 특정 패키지만 설치하려면 로컬에서
npm install @discordjs/voice@버전 --save로 lock을 갱신할 수 있다. - 설치 후 애플리케이션이 정상적으로 패키지를 찾는지
npm ls로 확인하고, 호스팅에서 시작 로그 확인.
마무리
npm ci 실패는 대부분 package.json과 package-lock.json 불일치에서 발생한다. 빠른 복구는 npm install로 가능하지만, 장기적으로는 로컬에서 lock 파일을 갱신해 커밋/업로드해 호스팅(디스호스트)에 배포하는 방식이 안전하다. 디스코드 봇을 안정적으로 호스팅하려면 lock 파일 관리를 습관화하자.