Workers Builds에서 engines.npm이 먹히지 않는 이유

package.json의 engines.npm에 버전을 적었는데, Workers Builds 로그에는 EBADENGINE 경고와 함께 기본 npm이 그대로 돈다. 원격 빌드의 npm 버전은 어디에서 정할까?

Workers Builds에서 engines.npm이 먹히지 않는 이유
세 줄 요약
  • Cloudflare Workers Builds는 package.json의 packageManager로 npm 버전을 지정한다.
  • 로컬에서는 npm ci가 성공하고 원격 빌드에서만 실패한다면 npm 버전 차이가 원인일 수 있다.
  • 버전을 맞춰도 lockfile과 package.json이 실제로 다르거나 설치 옵션이 다르면 실패할 수 있다.

npm 버전을 설치하는 설정은 packageManager다

Workers Builds에서 engines.npm을 바꿨는데도 예전 npm이 실행된다면 설정의 역할부터 구분해야 한다. Cloudflare는 10월 23일부터 packageManager를 통한 npm 버전 지정을 지원한다고 발표했다. 지정한 npm은 의존성 설치보다 먼저 준비된다.

빌드 이미지 문서에 따르면 engines.npm만 적었을 때는 기본 npm을 사용하며 버전 조건에 맞지 않으면 EBADENGINE 경고가 나타난다. 이 필드를 적는 것만으로 원하는 버전이 설치되지는 않는다.

로컬에서 성공한 npm 버전을 정확히 적는다

우선 프로젝트에서 npm -v로 실제 사용하는 버전을 읽는다. 그 버전을 package.json의 최상위 packageManager 항목에 적는다. 다음은 Cloudflare 문서의 예시이며, 11.19.1이 모든 프로젝트의 필수 버전이라는 뜻은 아니다.

{
  "packageManager": "[email protected]"
}

npm@^11처럼 범위로 쓰지 않고 정확한 버전을 지정해야 한다. 변경한 파일을 빌드 대상 커밋에 포함한 뒤에는 빌드 로그에서 선택된 npm과 의존성 설치 결과를 살펴보는 순서가 적절하다.

Cloudflare의 문제 해결 문서는 로컬의 npm ci는 성공하지만 원격에서 package.json과 lockfile이 맞지 않는다는 오류가 날 때, 새 npm으로 만든 잠금 파일을 빌드 이미지의 기본 npm이 다르게 처리할 가능성을 지목한다. 이 조건에서는 잠금 파일을 없애기 전에 두 환경의 설치 도구를 맞출 이유가 있다.

프로젝트 루트가 저장소 루트와 다르면 두 파일을 본다

Workers Builds는 설정된 프로젝트 루트의 package.json을 읽는다. 모노레포처럼 루트가 저장소 최상위와 다르면 저장소 최상위의 파일도 읽는다. 양쪽에 packageManager가 있다면 같은 값을 사용해야 한다.

이 항목은 패키지 관리자의 버전을 정한다. 어떤 관리자가 의존성을 설치할지는 저장소의 lockfile도 결정하므로, 필드 하나를 npm으로 바꾸는 것만으로 Yarn·pnpm 프로젝트의 이전이 끝나지는 않는다.

Node.js 버전도 별도다. 빌드용 Node는 NODE_VERSION이나 .nvmrc·.node-version으로 지정할 수 있다. npm 버전을 고정했다고 Node 버전까지 함께 고정됐다고 생각하면 다른 환경 차이를 놓칠 수 있다.

버전이 같다면 파일과 설치 옵션의 차이를 확인한다

npm ci의 동작은 잠금 파일에 고정된 의존성을 설치하는 것이다. package.json의 의존성 목록과 잠금 파일 내용이 실제로 어긋나면 오류로 끝나며, 잠금 파일을 자동 수정하지 않는다.

이 경우 로컬에서 필요한 의존성 변경과 잠금 파일을 함께 반영하고 다시 설치를 확인해야 한다. npm ci는 기존 node_modules를 지운 뒤 설치하므로, 실행할 작업 디렉터리도 확인한다.

잠금 파일 생성 때 --legacy-peer-deps나 --install-links처럼 의존성 트리에 영향을 주는 옵션을 썼다면 CI에도 같은 옵션이 필요하다. npm 문서는 프로젝트의 .npmrc로 설정을 함께 보관하는 방법을 안내한다. 따라서 원격 설치 실패를 좁혀 가는 기준은 npm 버전, 두 의존성 파일, 설치 옵션의 일치다.