당신이 corepack 을 사용해야 하는 이유

RexiaN·2025년 7월 1일
0

corepack 은 Node.js 프로젝트에 명시된 패키지 매니저를 설치하지 않고 바로 사용할 수 있게 해주는 도구이다.

corepack 은 무엇 일까?

corepack 은 node.js 프로젝트에서 패키지 매니저 호환성 이슈를 해결해주는 도구이다.

프로젝트마다 설치된 의존성들의 버전이 다르듯이 패키지 매니저의 종류와 버전도 다를 수 있다. 또한 패키지 매니저들은 각자의 lockfile(package-lock.json, yarn.lock, pnpm-lock.yaml)을 생성한다. lockfile 은 패키지 매니저의 버전에 영향을 받기 때문에 한 버전의 패키지 매니저만 사용하는 경우에도 호환성에 문제가 있을 수 있다. 그래서 나온 것이 바로 corepack 이다.

설치 및 사용법

먼저 설치되어 있는 yarnpnpm 을 제거한다.

npm uninstall -g yarn pnpm

만일 yarn 이나 pnpm 을 전역에 설치했는지 보고 싶다면 다음 명령어로 확인이 가능하다.

npm list -g --depth=0

yarnpnpm 을 제거했다면 npm 을 사용해서 corepack 을 설치하면 된다.

npm install -g 

이후에 corepack 을 활성화 시켜주면 된다. 어느 디렉토리에서 실행하던 상관 없다.

corepack enable

이제 프로젝트 디렉토리로 이동해서 원래 하던것처럼 yarn, pnpm 명령어를 사용하면 된다.

현재 프로젝트에 패키지 매니저 정의하기

프로젝트에 특정 버전의 패키지 매니저를 정의하고 싶을 수 있다. 그럴때엔 프로젝트로 이동한 뒤 corepack use {packageManager}@{semVer} 명령어를 실행하면 된다. 버전의 제일 앞자리만 입력하면 알아서 제일 안전한 버전으로 설치를 해준다. 자신이 사용하고자 하는 패키지 매니저와 메이저 버전을 입력하자.

~/Documents/next-ascii-art ❯ corepack use yarn@4
Installing yarn@4.9.2 in the project...

➤ YN0000: · Yarn 4.9.2
➤ YN0000: ┌ Resolution step
...
➤ YN0000: · Done with warnings in 6s 161ms

이제 package.json 파일을 보면 packageManager 필드가 추가된 것을 볼 수 있다.

{
  "packageManager": "yarn@4.9.2+sha512.1fc009bc09d13cfd0e19efa44cbfc2b9cf6ca61482725eb35bbc5e257e093ebf4130db6dfe15d604ff4b79efd8e1e8e99b25fa7d0a6197c9f9826358d4d65c3c"
}

Corepack 의 역할

이제 우리가 패키지 매니저를 통해 프로젝트를 실행할 때 Corepack 이 호출을 가로챈 뒤 상황에 따라 다르게 동작한다.

1.현재 프로젝트가 사용중인 패키지 매니저용으로 설정되어 있는 경우

  • 예: pnpm 기반 프로젝트에서 pnpm 명령어 실행

Corepack 이 호환되는 최신 버전을 다운로드 하고 캐시한다.

2.현재 프로젝트가 다른 패키지 매니저용으로 설정되어 있는 경우

  • 예: yarn 기반 프로젝트에서 pnpm 명령어 실행

Corepack 이 올바른 패키지 매니저를 사용하라고 요구한다.

실제로 yarn 4버전으로 작업하는 nextjs 프로젝트에서 pnpm dev 를 실행했을 때 This project is configured to use yarn because /Users/jinhyuckkim/Documents/next-ascii-art/package.json has a "packageManager" field라는 문구가 나오며 실행이 되지 않는다.

3.현재 프로젝트에 어떤 패키지 매니저도 설정되어 있지 않은 경우

Corepack 은 사용자가 무엇을 하는지 알고 있다고 가정하고 안정적인 릴리즈로 고정된 패키지 매니저 버전을 사용한다.

번외: fnm 에서 corepack 활성화 하기

나는 개인적으로 Node 버전들을 fnm 으로 관리하고 있다. fnm 은 rust 로 작성된 단일 바이너리 파일로 크기가 작고 bash 스크립트로 작성되어 있는nvm 에 비해 훨씬 빠르다. fnm 으로 새로운 노드 버전을 설치할 때 --corepack-enabled 커맨드를 추가하여 fnm 이 모든 Node.js 설치에서 corepack enable 커맨드를 호출하게 할 수 있다.

fnm install 20 --corepack-enabled

이 명령어는 다음 작업을 수행한다.
1. fnm이 Node.js v20을 다운로드하고 설치한다.
2. 설치가 완료된 직후, fnm은 해당 Node.js 버전에 대해 자동으로 corepack enable을 실행한다.
3. 따라서 fnm use 20으로 버전을 바꾸기만 하면 별도의 설정 없이 바로 pnpm이나 yarn 같은 패키지 매니저를 사용할 수 있다.

나는 Node.js 의 LTS 버전이 나오면 당장 사용하지는 않더라도 설치를 해두는 편인데 해당 명령어로 corepack 을 신경쓰지 않고 노드 버전을 왔다갔다 하면서 잘 사용하고 있다.

번외: lockfile 이 패키지 매니저의 버전에 영향을 받는 이유

lockfile은 단순히 패키지 버전만 기록하지 않는다. 패키지 매니저의 의존성 해결 알고리즘 의 결과물이다.

같은 패키지 매니저라 하더라도 버전마다 의존성을 해석하고 배치하는 내부 로직이 다를 수 있다. 예를 들어 npm v2는 하위 디펜던시를 상위 디펜던시 폴더 아래에 두지만 npm v3 는 하위 디펜던시를 위로 끌어올려서(디펜던시 호이스팅) 같은 계층에 두고 관리한다.

또한 lockfile 자체의 포맷이 변경될 수 도 있다. 패키지 매니저의 메이저 버전이 업데이트 될 때 lock 파일의 구조를 다르게 가져갈 수 있기 때문에 구버전의 패키지 매니저는 신버전의 lockfile 을 해석하지 못할 수 있다.

그 외에도 패키지 매니저의 버전이 올라갈 때 마다 성능 최적화나 보안 강화를 위해 lockfile 에 새로운 정보들을 추가하기도 한다. 구버전의 패키지 매니저응 이런 새롭게 추가되는 정보들을 이해하지 못하고 무시하거나 충돌을 일으킬 수 있다.

결정적 설치(deterministic Installs)란?

결정적 설치란, package.json에 ^5.0.0처럼 버전 범위가 유연하게 지정되어 있어도, 프로젝트에 참여하는 모든 개발자가 언제나 정확히 동일한 버전의 패키지들을 설치하도록 보장하는 것을 의미한다.

lockfile은 현재 설치된 모든 패키지(및 그 하위 패키지들)의 정확한 버전, 다운로드 위치, 무결성 해시값 등을 기록하여 이 문제를 해결한다.

profile
Don't forget Rule No.1

0개의 댓글