Val Town은 엄청나게 많은 의존성을 가진 리액트 애플리케이션입니다. 복잡하고 항상 의존성 업그레이드를 처리해야 합니다. 이 웹을 과도하게 복잡하게 만드는 중대한 죄를 저지르고 있습니다. 이 글을 쓰는 시점에서 node_modules 디렉토리가 863MB입니다. 휴!

그런데 정말 그럴까요? 우리가 기술 부채를 이곳저곳에서 쌓아가며 마음대로 의존성을 설치하고 있는 걸까요? 저는 그렇지 않다고 말하고 싶습니다.
사실 우리가 만들려는 것에는 본질적인 복잡성이 있습니다. 직접 타입스크립트 트랜스파일러를 만들거나 CodeMirror 설치를 피하고 코드 편집에 textarea를 사용하지는 않을 것입니다. 저는 매주 조금씩 시간을 들여 package.json을 살펴보며 이 중에 어떤 걸 제거할 수 있을까?를 생각합니다. 가끔 제거할 수 있는 의존성을 찾기도 하지만, 대부분은 빈손으로 돌아옵니다. 우리는 실제로 이 모든 것들이 필요합니다. 원칙이 현실과 만나는 방식을 힘들게 배우면서, 다른 사람들을 판단하는 제 능력은 점점 희미해집니다.
그렇다고 의존성 관리에 기술이 필요 없다는 뜻은 아닙니다. 제가 개발해온 일반적인 의존성 위생에 함께 맞아떨어지는 여러 기법과 도구들이 있습니다. 이걸 어딘가에 완전히 적어둔 적은 없는 것 같네요. 한 번 시도해보겠습니다.
모든 새 의존성을 읽어보세요 (리액트는 제외)
규칙 1은 읽는 것입니다. 이건 정말 문자 그대로입니다. 프로젝트에 도입하려는 모든 의존성의 소스 코드를 읽으세요. 물론 README도요. 저는 눈과 두뇌를 사용하는 전통적인 방식으로 하는 것을 강력히 추천하지만, 그게 더 편하다면 LLM도 도움이 될 수 있습니다. 하지만 전체 작업을 로봇에게 맡기지는 마세요. 실제 이해가 목표이고, 이건 누군가를 통해 대신 이룰 수 있는 게 아닙니다.
이런 작업을 하다 보면, 추가하려는 새 의존성이 겨우 50줄짜리 코드에 불과한 경우도 꽤 자주 있습니다. 이럴 때는 NPM으로 설치하기보다는 벤더링(vendoring) 하는 편이 낫습니다.
코드를 그대로 복사해 오고, 오픈소스 라이선스만 코드 주석으로 남기면 충분합니다.
또는 모듈의 용량이 gzip 기준으로 2MB에 달하고, 전이 의존성(transitive dependency)도 3개나 추가되는데, 정작 내가 쓰는 코드는 그중 50줄뿐이라는 걸 깨닫게 될 수도 있습니다. 이런 상황 역시 바람직하지 않습니다. 실질적인 이득은 거의 없고, 부담만 크게 늘어나기 때문입니다. node_modules에 더 많은 공간을 차지하거나, 사용하지 않는 부분에 보안 취약점이 있을 수 있고 똑같이 대응해야 할 것입니다.
저는 리액트와 다른 메가 의존성들에 대해서는 예외를 둡니다. 리액트의 알고리즘과 타입스크립트 컴파일러 코드 내부를 본 적이 있고, 그냥 그 회사의 천재들을 믿어야겠다고 결정했습니다.
읽지 않으면 성공하지 못합니다.
npm ls와 package-lock.json 과 친해지세요
또는 pnpm을 사용한다면 pnpm-lock.yaml과 pnpm why를 사용하세요. 그리고 다른 패키지 매니저를 사용한다면 비슷한 명령어를 사용하세요. 이유는 꽤 간단합니다. 직접 설치한 의존성은 빙산의 일각이며, 실제로 node_modules를 채우는 것은 그것들이 끌어오는 전이 의존성입니다. 그리고 그 전이 의존성은 매우 중요합니다.
예를 들어, 프로젝트에서 타입스크립트를 트랜스파일해야 한다고 가정해봅시다. 이미 트랜스파일러가 설치되어 있을 가능성이 꽤 높습니다. 프로젝트에는 drizzle-kit, Vite, 그리고 tsx에 의해 끌려온 esbuild 복사본들이 있습니다. 그래서 esbuild를 직접 의존성으로 추가하더라도 실제 비용은 거의 들지 않습니다. 내부적으로는 기존에 사용하던 동일한 esbuild 바이너리로 중복 제거(dedupe)되기 때문입니다. 이것은 유용한 작은 게임입니다. 애플리케이션에 무언가를 설치할 때, 이미 전이적으로 설치된 것을 재사용할 수 있는 방법을 찾을 수 있다면, 의존성을 무료로 얻을 수 있습니다!
그리고 package-lock.json 또는 pnpm-lock.yaml을 읽으세요. 그렇게 나쁘지 않고, 뭔가를 배울 것입니다. 거기에는 많은 것들이 있습니다. 다른 사람들이 의존하는 모듈에 익숙해지면, 머릿속에 작은 PageRank 알고리즘이 만들어져서 새로운 것을 위해 무엇을 사용할지 즉시 떠올릴 수 있습니다. 호기심을 충족시키고 그 npmjs.com 웹페이지들을 여세요.
패키지의 실제 크기를 분석하는 것은 꽤 멋집니다
큰 NPM 모듈의 두 가지 명확한 영향이 있습니다. 배포된 애플리케이션에 대한 기여도와 애플리케이션을 개발하는 동안 node_modules에서 차지하는 공간입니다. 애플리케이션 크기에 먼저 집중하는 것이 좋지만, 둘 다 중요합니다. node_modules에 2기가바이트의 코드에 의존하는 애플리케이션은 CI에서 테스트하기가 꽤 느릴 것이고, 더 많은 다운로드를 필요로 하기 때문에 배포도 느려질 것입니다.

저는 디스크의 node_modules를 추적하기 위해 20년 동안 있어온 빈티지 애플리케이션인 Grand Perspective를 사용하지만, Linux나 Windows를 사용한다면 고려할 만한 다른 디스크 공간 분석기들이 많이 있습니다.
배포된 애플리케이션의 크기를 분석하는 것은 훨씬 더 복잡하고 시스템마다 다릅니다. 여기선 Vite와 함께 React Router를 사용하고 있어서 rollup-plugin-visualizer가 솔루션이지만, 모든 번들러마다 다르고 Next.js의 번들 분석기처럼 일부 프레임워크는 자체 솔루션을 가지고 있습니다.
좋은 NPM 모듈을 만드는 것은 무엇일까요
하지만 정말로 무엇을 찾고 있나요? 좋은 모듈의 정의는 계속 변하지만, 꽤 자주 이런 식으로 보일 것입니다. 적절한 유지보수 이력, 내장된 타입스크립트 타입, 통과하는 테스트, 좋은 문서.
한마디로 줄이면 실력의 분위기가 느껴져야 한다는 말입니다.
즉흥적으로 무언가를 만들고 많은 실수를 하더라도, 사용하는 부품들은 견고하기를 원합니다. 애플리케이션의 버그는 여러분이 작성하는 버그와 다른 사람들로부터 상속받는 버그의 총합이므로, 설치하는 코드에 대해 작성하는 코드보다 더 높은 기준을 가지는 것은 실제로 공정합니다.
나쁜 모듈을 만드는 것은 무엇일까요? 물론 방치되고 형편없이 작성된 것도 나쁘지만, 그보다 더 나쁜 것은 잘못된 문제를 해결하는 모듈입니다. 실제 문제에 맞지 않아서 문제 자체를 모듈에 맞게 바꿔야 하는 것 말이죠. 이는 코드를 읽고, 문제와 솔루션을 이해하는 데 약간의 시간을 들이면 이것을 피할 수 있습니다. 아니면 LLM에게 물어보세요, 아이처럼요.
사용하지 않는 것은 제거하고 나머지는 최신 상태로 유지하세요

Renovate를 사용해야 합니다. 모듈을 최신 상태로 유지하도록 잔소리할 것이고, 연간 한 번에 하는 것보다 점진적으로 그런 종류의 작업을 하는 것이 더 낫습니다.
그리고 Knip을 사용해야 합니다. 그것은 그야말로 마법입니다. 너무 빠르고, 극도로 정확합니다. package.json에 명시했지만 실제로는 사용하지 않는 모듈들을 알려줄 것입니다. 프로젝트의 이전 버전에서 온 많은 쓰레기들이 있는 것을 놓치기가 너무 쉽습니다. Knip으로 제거하세요! 프로젝트에서 더 이상 사용하지 않는 파일들도 보여줄 것입니다. Knip 티셔츠가 있다면 지금 당장 입고 있을 것입니다. 그 정도로 좋습니다.
좋은 모듈을 작성하는 사람들의 빠른 치트시트를 가지세요
NPM 모듈 생태계는 사람들로 이루어져 있습니다. 그 사람들이 누구인지 아는 것이 유용합니다! 예를 들어, Promise와 관련된 것(또는 다른 많은 주제)을 찾고 있을 때, Sindre Sorhus가 이미 무언가를 게시했는지 확인합니다. 아주 자주 그가 했어요!
많은 견고한 작업을 가진 다른 사람들도 알아두면 좋습니다. isaacs, Matteo Collina, Mafintosh 같은 분들이요.
마크다운과 관련된 작업을 하고 있다면, 모든 wooorm과 unified 저장소를 알아야 합니다. 차세대 Node.js 관련? unjs를 확인하세요. 트랜스파일러 내부는 항상 Rich Harris의 프로젝트를 확인해야 하는데, 여기에는 정말 많은 보석들이 포함되어 있습니다.
원한다면 AGENTS.md 파일에 넣을 수도 있는 의존성의 시작점만 포함하는 후속 게시물을 기대하세요.
의존성은 불가피합니다
그것이 진실입니다. 우리는 모두 서로의 어깨 위에 서서 만들고 있습니다. 하지만 어떤 어깨 위에 서야 할지 찾는 데는 기술이 있습니다.
어떤 면에서는 웹 플랫폼과 NPM 모듈 생태계가 너무 빠르게 움직이고 너무 많은 까다로운 업데이트와 결정을 요구한다는 것이 답답합니다. 하지만 그것은 거의 규범입니다. NPM과 Node의 교훈을 배운 차세대 언어들조차도 비대해진 패키지 생태계로 고통받습니다. 의존성 관리는 일의 일부이고 개발자는 그것을 잘해야 합니다.
'Web Frontend Developer' 카테고리의 다른 글
| [번역] HTTP 캐싱 완벽 가이드 (1) | 2025.11.20 |
|---|---|
| [요즘IT] 프론트엔드 개발자가 써본 "피그마 MCP"의 가능성과 한계 (0) | 2025.11.05 |
| [번역] 웹어셈블리(Wasm) 3.0 (0) | 2025.10.23 |
| 2024년 자바스크립트 트렌드 돌아보기 (4) | 2025.01.31 |
| 패스트캠퍼스 컨퍼런스인 캠프콘을 준비하며 (2) | 2024.03.30 |