package.json과 package-lock.json, node_modules, workspaces를 이해하면 npm 명령을 단순히 실행하는 데서 벗어나 설치 문제를 직접 진단할 수 있어.
package.json은 프로젝트의 manifest야. 이름, 버전, 스크립트, 런타임·개발·peer 의존성, main·module·exports 같은 진입점과 메타데이터를 선언해. 모든 JavaScript 도구가 읽는 프로젝트의 신분증이므로 변경할 때마다 버전 관리에 포함해.
package-lock.json은 전이 의존성과 콘텐츠 해시까지 포함한 정확한 설치 트리를 기록해. 팀원과 모든 CI 실행이 같은 바이트를 설치하도록 보장하므로 항상 버전 관리에 넣어야 해. 직접 편집하지 말고 npm만 이 파일을 다시 쓰게 해.
node_modules/는 패키지가 실제로 놓이는 디렉터리야. 크고 플랫폼에 따라 달라지는 생성물이므로 절대 버전 관리에 넣지 말고 항상 .gitignore에 추가해. npm은 공통 의존성을 위로 끌어올리는 평평한 구조를 주로 써서 빠르지만, package.json에 없는 패키지를 우연히 불러오는 phantom dependencies를 허용해. pnpm은 이 문제를 막지만 npm은 막지 않아.
Workspaces를 사용하면 한 저장소에서 여러 하위 패키지를 관리할 수 있어. 루트 package.json의 workspaces 배열에 각 경로를 선언하면 npm이 공유 의존성을 루트 node_modules로 끌어올려. 기본적인 monorepo 지원으로는 충분히 작동하지만 pnpm과 Yarn이 더 강력해.