PNPM v10 braking changes

February 11, 2025


본 글은 PNPM 문서와 조사한 자료를 바탕으로 claud.ai가 작성한 글입니다

들어가며

PNPM v10에서 가장 주목할 만한 변경사항 중 하나는 패키지 호이스팅 정책의 변화입니다. 이번 글에서는 이전 버전과 v10에서의 호이스팅 동작 방식 차이를 자세히 살펴보고, 실제 프로젝트에서 어떻게 대응해야 하는지 알아보겠습니다.

PNPM의 기본 철학: Strict한 격리

PNPM은 기본적으로 엄격한 패키지 격리를 지향합니다. 이는 다음과 같은 특징을 가집니다:

  1. 모든 의존성은 node_modules/.pnpm 디렉토리에 저장
  2. 각 패키지는 package.json에 명시된 직접적인 의존성만 접근 가능
  3. Symlink를 통한 의존성 연결

이러한 구조는 node_modules 지옥을 방지하고, 잠재적인 보안 위험을 줄여줍니다.

v9까지의 호이스팅 정책

이전 버전에서는 개발자 경험(DX)을 위해 특정 패키지들에 대해 자동 호이스팅을 제공했습니다.

node_modules
├── .pnpm/          # 실제 패키지들이 저장되는 위치
├── eslint/         # 자동으로 호이스팅된 eslint
├── prettier/       # 자동으로 호이스팅된 prettier
└── your-project/   # 프로젝트 의존성

자동 호이스팅되는 패키지들

  • ESLint 관련 패키지
  • Prettier 관련 패키지
  • 일부 개발 도구

이는 VSCode 등의 IDE에서 포맷터나 린터를 쉽게 찾을 수 있도록 하기 위한 것이었습니다.

v10의 변경된 호이스팅 정책

v10에서는 보안 강화를 위해 자동 호이스팅을 완전히 제거했습니다.

node_modules
└── .PNPM/          # 모든 패키지가 이곳에만 저장됨

이제는 모든 호이스팅이 명시적인 설정을 통해서만 가능합니다:

{
  "pnpm": {
    "public-hoist-pattern": [
      "*eslint*",
      "*prettier*",
      "@types/*",
      "typescript"
    ]
  }
}

마이그레이션 가이드

1. 필요한 도구 파악하기

먼저 프로젝트에서 호이스팅이 필요한 도구들을 파악합니다:

  • IDE 플러그인이 필요로 하는 패키지
  • 글로벌 접근이 필요한 개발 도구
  • TypeScript 관련 패키지

2. package.json 설정하기

{
  "pnpm": {
    "public-hoist-pattern": [
      // 린터/포맷터
      "*eslint*",
      "*prettier*",

      // TypeScript
      "@types/*",
      "typescript",

      // 기타 개발 도구
      "*webpack*",
      "*babel*"
    ],
    // 호이스팅된 패키지의 중복 설치 방지
    "shamefully-hoist": false
  }
}

변경의 의미

이번 변경은 다음과 같은 의미를 가집니다:

  1. 보안 강화: 의도하지 않은 패키지 접근을 원천 차단
  2. 명시성 증가: 호이스팅이 필요한 패키지를 명확히 문서화
  3. 의존성 관리 개선: 잠재적인 충돌과 버전 불일치 방지

마치며

PNPM v10의 호이스팅 정책 변경은 단기적으로는 추가 설정이 필요한 불편함을 가져올 수 있습니다. 하지만 장기적으로는 더 안전하고 예측 가능한 의존성 관리를 가능하게 할 것입니다. 특히 대규모 프로젝트나 모노레포 환경에서 이러한 엄격한 관리는 큰 이점이 될 수 있습니다.

더 자세한 내용은 PNPM v10 Braking changes를 참고하시기 바랍니다.