package.json Diff: npm 매니페스트 온라인 비교
왼쪽에 이전 package.json을, 오른쪽에 새 package.json을 붙여넣으면 어떤 dependencies, scripts, engines가 바뀌었는지 정확히 확인할 수 있습니다. 브라우저에서 실행되며 아무것도 업로드되지 않습니다.
이 package.json diff 도구란
두 개의 npm package.json 파일을 나란히 비교하기 위한 무료 브라우저 내 도구입니다. 이전 매니페스트를 왼쪽에, 새 매니페스트를 오른쪽에 붙여넣으면 차이점이 문자 단위로 강조 표시됩니다. 텍스트는 컴퓨터를 떠나지 않으며, 이는 매니페스트가 비공개 저장소나 미출시 제품에 속할 때 중요합니다.
Renovate나 Dependabot PR이 들어와서 버전 bump를 넘어 실제로 무엇이 변경되었는지 알아야 하는 순간을 위해 만들어졌습니다. 누군가 script 편집을 끼워 넣지 않았나? engines 필드가 Node 18에서 Node 20으로 옮겨졌나? peerDependency가 더 엄격해졌나? GitHub의 diff 뷰가 일부 답을 주지만, 여러 PR을 연달아 살펴보거나 아직 push되지 않은 브랜치를 비교할 때는 두 매니페스트를 깔끔한 두 패널 뷰에 붙여넣는 게 더 빠릅니다.
내부적으로 이것은 우리의 compare-json 페이지를 동작시키는 것과 같은 JSON을 인지하는 diff이며, npm 및 yarn 워크플로우에 맞게 프레이밍과 문구를 조정했습니다. 두 매니페스트는 diff가 실행되기 전에 JSON으로 파싱되고 보기 좋게 출력되므로, 외관상의 공백 차이가 강조 표시를 오염시키지 않습니다. JSON이 아닌 매니페스트 형식의 원시 텍스트 diff가 필요하다면 compare-text 도구가 그것을 다루고, compare-yaml이 pnpm-lock.yaml을 처리합니다.
diff가 실제로 작동하는 방식
각 패널은 JSON으로 파싱됩니다. 파싱이 성공하면 매니페스트는 일관된 두 칸 들여쓰기로 다시 포맷되고 키 순서는 작성된 그대로 유지됩니다. 파싱이 실패하면 (잘못된 쉼표, 누락된 중괄호, 너무 적은 문자를 잡은 복사-붙여넣기) 도구는 일반 텍스트 모드로 폴백하여 어느 줄이 깨졌는지 알려줍니다. 양쪽이 유효한 JSON이 되면 diff는 문자 단위로 실행되고, 그 다음 의미적 정리 패스가 변경 사항을 읽기 쉬운 덩어리로 다시 그룹화하므로 ^18.2.0에서 ^19.0.0으로의 버전 bump는 9개의 문자 편집이 아닌 한 번의 편집으로 읽힙니다.
오른쪽 패널의 삽입은 녹색으로, 왼쪽 패널의 삭제는 빨간색으로 렌더링됩니다. 두 패널은 함께 스크롤 잠금되므로 한쪽에서 devDependencies 깊숙이 변경 사항을 찾으면 다른 쪽이 같은 키로 점프합니다. diff는 보기 좋게 출력한 후의 텍스트 수준이므로 사람이 읽는 방식대로 구조적 변경을 봅니다: 제거된 의존성은 줄로 사라지고, 변경된 semver 범위는 값 안에서 강조되며, 새 script는 배치한 위치의 scripts 블록에 들어갑니다.
도구가 의도적으로 하지 않는 것: 의존성 리졸버가 아닙니다. caret 범위 bump가 어떤 추이적 패키지를 끌어오는지, peer가 충족되었는지, 새 버전이 보안 권고를 도입하는지 알려주지 않습니다. 그것을 위해서는 로컬에서 npm install 후 npm audit를 실행하거나, Snyk나 GitHub의 Dependabot 알림 같은 lockfile을 인지하는 서비스와 함께 npm을 사용하세요. 이 페이지는 매니페스트 텍스트가 무엇을 말하는지 알려줍니다. 해석 작업은 패키지 매니저의 일입니다.
세 단계로 package.json diff 하는 방법
두 개의 텍스트 패널, 한 번의 diff. CLI 플래그 없음, 설치 단계 없음, 읽을 패치 형식 없음.
- 1
왼쪽에 이전 매니페스트 붙여넣기
에디터에서, git show main:package.json에서, 또는 팀원으로부터 package.json의 이전 버전을 복사합니다. 왼쪽 패널에 붙여넣습니다. 도구는 그것을 JSON으로 파싱하고 보기 좋게 출력합니다. JSON이 유효하지 않으면 에디터가 파싱 오류를 표시하므로 diff하기 전에 스니펫을 수정할 수 있습니다.
- 2
오른쪽에 새 매니페스트 붙여넣기
업데이트된 버전으로 같은 작업을 합니다. Renovate나 Dependabot PR을 검토하고 있다면 가장 쉬운 출처는 PR 브랜치의 원시 파일입니다. 두 파일은 일관된 들여쓰기로 보기 좋게 출력되므로 외관상의 공백 편집은 diff에 가짜 변경으로 나타나지 않습니다.
- 3
강조된 차이 읽기
삭제는 왼쪽에 빨간색 취소선으로, 삽입은 오른쪽에 녹색으로 표시됩니다. 의존성 블록을 먼저 살펴본 다음 명령 편집을 위해 scripts 섹션을 확인하고, 그 다음 engines와 peerDependencies 필드를 확인합니다. 단일 값 내의 버전 bump는 변경된 문자를 강조하므로 패치 bump와 메이저 bump를 한눈에 구별할 수 있습니다.
package.json diff가 옳은 선택일 때
Renovate나 Dependabot PR 검토
봇이 한 아침에 15개의 PR을 엽니다. 대부분은 일상적이지만 하나에 script 변경, 또는 조여진 peerDependency, 또는 CI 이미지를 깨는 engines bump가 끼어 있습니다. PR 제목은 "chore(deps): bump foo from 4.1.0 to 4.2.1"이라 적혀 있고, 자동 운전으로 신뢰합니다. 전후 package.json을 diff에 붙여넣으면 다른 어떤 것도 움직이지 않았음을 5초 만에 확인할 수 있습니다. 이것이 JS 엔지니어가 매니페스트 diff에 손을 뻗는 가장 흔한 이유입니다.
병합 전 두 브랜치 비교
당신과 동료 모두 별도의 기능 브랜치에서 package.json을 건드렸습니다. 편집이 다른 블록에 있기 때문에 Git은 깔끔하게 병합할 것이지만, 깔끔한 병합이 정확한 병합을 의미하지는 않습니다. 한 브랜치가 떨어뜨린 script, 한 브랜치가 다운그레이드한 의존성, 또는 두 브랜치가 다른 버전으로 같은 패키지를 추가한 충돌을 발견하기 위해 두 브랜치의 매니페스트를 diff에 붙여넣으세요. CI가 병합된 결과에 대해 npm ci를 실행한 후 발견하는 것보다 저렴합니다.
npm install이 package-lock.json에 승격시킨 것 감사
package.json을 편집하는 것은 변경의 절반입니다. 나머지 절반은 package-lock.json이 해석된 트리에 대해 기록하는 것입니다. npm install을 실행한 후, 이전 lockfile을 새 lockfile 옆에 붙여넣어 어떤 추이적 패키지가 함께 왔는지 확인합니다. caret 범위가 깊이 중첩된 의존성의 새 minor를 끌어왔을 때 놀라운 추가가 흔합니다. 원시 lockfile 검사에는 compare-json 페이지가 더 큰 파일을 더 잘 처리합니다. 이 페이지는 매니페스트 자체에 가장 적합합니다.
회귀 후 다운그레이드 확인
릴리스가 출시되고, 버그가 나타나고, bisect를 하고, 용의자는 의존성 트리 어딘가에 있습니다. 마지막으로 좋았던 릴리스의 package.json을 현재 것 옆에 붙여넣습니다. 변경되지 않은 블록은 머릿속에서 제외하고 강조 표시된 버전 범위에 집중합니다. 수정은 종종 마지막 녹색 빌드에 고정된 버전으로 한 라이브러리를 다운그레이드하는 것입니다. 용의자를 찾으면 상위 문제가 해결될 때까지 정확한 버전(caret 없음, tilde 없음)으로 잠그세요.
로컬 매니페스트를 팀원의 것과 비교
두 명의 엔지니어, 까다로운 병합 한 번, 리베이스 끝에 두 개의 다른 package.json 파일. lockfile은 더 혼란스럽습니다. 두 매니페스트를 나란히 붙여넣어 어떤 키가 일치하지 않는지 확인하고, git merge -X theirs의 결과를 읽지 않고 받아들이는 대신 신중하게 해결합니다. 또한 npm install이 당신의 것과 다른 트리를 가져오고 매니페스트 드리프트가 의심되는 새 기여자를 온보딩할 때 올바른 도구입니다.
라이브러리 package.json의 publish 전 검토
라이브러리에서 npm publish를 실행하기 전에 중요한 매니페스트 필드는 앱과 다릅니다: main, module, types, exports, files, peerDependencies, engines. publish 직전 매니페스트를 마지막으로 publish된 것과 diff하세요. 떨어진 peerDependencies 항목, 변경된 exports 조건, 또는 조여진 engines 범위는 npm 자체가 경고하지 않는 방식으로 소비자를 깨뜨릴 수 있습니다. Node.js packages docs가 그 필드들의 의미에 대한 참조입니다.
알아둘 가치가 있는 package.json 필드
실제 package.json diff에 나타나는 필드와 그 의미. Renovate PR을 승인하거나 둘 다 매니페스트를 건드린 두 브랜치를 병합하기 전에 살펴볼 가치가 있습니다.
| Topic | What this tool does |
|---|
| dependencies vs devDependencies vs peerDependencies | dependencies는 패키지와 함께 출시되며 그것을 소비하는 누구나 설치합니다. devDependencies는 프로젝트 루트에서 npm install을 실행할 때만 설치되고, 하위 소비자에게는 결코 설치되지 않습니다. peerDependencies는 라이브러리가 호스트가 제공할 것으로 예상하는 패키지(일반적으로 React, 테스트 프레임워크, 번들러)이며 npm 7+는 충돌하지 않는 한 자동으로 설치합니다. 이러한 블록 간에 패키지를 옮기는 것은 누가 설치 비용을 지불하는지를 변경합니다. |
|---|
| caret (^) vs tilde (~) semver 범위 | caret ^1.2.3은 2.0.0을 포함하지 않는 어떤 버전이든 허용합니다. 이것은 npm의 기본값이며 가장 느슨한 일반적인 범위입니다. tilde ~1.2.3은 1.3.0을 포함하지 않는 패치만 허용합니다. 1.2.x는 tilde와 같습니다. *는 어떤 버전이든 의미합니다(프로덕션에서 사용하지 마세요). latest는 설치 시점에 해석되어 재현 불가능한 빌드를 생성하므로 피하세요. |
|---|
| 정확한 고정 (범위 접두사 없음) | caret이나 tilde 없이 "react": "18.2.0"이라고 쓰면 그 정확한 버전에 고정됩니다. lockfile과 결합하면 보안 패치를 자동으로 받지 않는 비용으로 가장 재현 가능한 설치를 얻습니다. 일부 팀은 모든 것을 고정하고, 다른 팀은 caret 더하기 lockfile 조합에 의존합니다. 보편적으로 옳은 답은 없지만, 절충점은 더 결정적인 빌드 대 더 오래된 의존성입니다. |
|---|
| package-lock.json 결정성 | package-lock.json은 추이적을 포함한 의존성 트리의 모든 패키지의 정확한 해석된 버전을 기록합니다. npm ci는 lockfile에서 설치하고 수정을 거부합니다. npm install은 범위가 더 새로운 버전을 허용하면 업데이트할 수 있습니다. CI에서는 항상 npm ci를 사용하세요. 개발자에게는 결과적인 lockfile 변경을 커밋하는 한 npm install이 괜찮습니다. |
|---|
| 모노레포용 workspaces 필드 | workspaces 배열은 모노레포에서 형제 디렉터리를 연결된 패키지로 취급하라고 npm에 알립니다. 루트에서의 npm install은 모든 workspaces를 설치하고 단일 호이스트된 node_modules 트리를 만듭니다. Yarn과 pnpm은 자체 관례로 workspaces를 지원하며, 특히 pnpm은 덜 공격적으로 호이스트하므로 설치 시점에 더 많은 의존성 누수 버그를 잡습니다. |
|---|
| engines 필드 | engines.node는 패키지가 지원하는 Node.js 버전을 선언합니다. 기본적으로 npm은 호스트가 이를 위반할 때만 경고합니다. .npmrc의 engine-strict=true가 그것을 하드 에러로 만듭니다. engines 필드를 bump하는 것은 오래된 Node에 갇힌 소비자에게 깨뜨리는 변경이며, Renovate "chore" PR 안에 숨는 종류의 변경입니다. 항상 engines diff를 읽으세요. |
|---|
| ES modules용 exports 필드 | exports 필드는 소비자가 패키지에서 어떤 경로를 임포트할 수 있는지와 어떤 조건(import, require, types, node, browser)이 어떤 파일로 해석되는지 제어합니다. 항목을 추가하거나 제거하는 것은 하위 코드에 깨뜨리는 변경입니다. Node.js packages documentation이 해석 규칙을 자세히 다룹니다. 의도적으로 새 진입점을 추가하지 않는 한 어떤 exports diff든 메이저 버전 가치의 편집으로 취급하세요. |
|---|
| package.json 내 파일 순서 | package.json의 최상위 키에는 강제된 순서가 없습니다. 관례상 대부분의 프로젝트는 name, version, description으로 시작한 다음 scripts, 그 다음 의존성으로 시작합니다. 의존성 블록 내에서는 키별 알파벳 순서가 사실상의 표준이며 대부분의 패키지 매니저는 저장 시 블록을 정렬합니다. 재정렬되었지만 그 외에는 동일한 항목을 보여주는 diff는 보통 도구의 차이이지 실제 변경이 아닙니다. |
|---|
package.json diff: 자주 묻는 질문
npm diff나 npm-check-updates와 어떻게 다른가요?
npm diff는 tarball과 소스를 포함하여 registry의 두 출시된 버전의 패키지를 비교하는 내장 npm 명령입니다. npm-check-updates (ncu)는 매니페스트의 어떤 의존성에 더 새로운 버전이 사용 가능한지 보고합니다. 둘 다 디스크에 있거나 두 브랜치에 있는 임의의 두 package.json 파일 간의 차이를 보여주지 않습니다. 이 도구가 그것을 합니다. 업그레이드해야 한다는 것을 알기 위해 ncu를, 릴리스 간 registry 측 변경을 보기 위해 npm diff를, 자신의 전후 매니페스트를 나란히 보기로 읽기 위해 이 페이지를 사용하세요.
보안을 감사하거나 알려진 취약점을 확인하나요?
아니요. 이 페이지는 텍스트만 diff합니다. npm registry, GitHub Advisory Database, 또는 어떤 취약점 서비스에도 질의하지 않습니다. 보안 감사를 위해서는 설치된 트리에 대해 npm audit를 실행하고, 패키지 출처를 확인하기 위해 npm audit signatures를 사용하거나, Snyk, Socket, Dependabot 알림에 의존하세요. 이 도구는 매니페스트에서 무엇이 변경되었는지 알고 싶을 때 옳은 선택입니다. 변경 사항이 출시하기에 안전한지 알고 싶을 때는 잘못된 선택입니다.
추이적 의존성 변경을 감지하나요?
매니페스트 단독으로는 아닙니다. package.json은 직접 의존성과 그 요청된 범위만 나열합니다. 추이적을 포함한 완전한 해석된 트리는 package-lock.json (또는 yarn.lock 또는 pnpm-lock.yaml)에 있습니다. 해석된 트리를 비교하려면 두 lockfile을 diff에 붙여넣으세요. lockfile은 크기 때문에 compare-json 페이지가 이것보다 더 잘 처리합니다. 특히 pnpm-lock.yaml에는 compare-yaml을 사용하세요. 이 페이지는 매니페스트에 최적화되어 있습니다.
두 package-lock.json 파일을 어떻게 비교하나요?
매니페스트와 같은 방식으로 두 lockfile을 패널에 붙여넣으세요. 도구가 그것들을 JSON으로 파싱하고, 보기 좋게 출력하고, diff합니다. lockfile이 수천 줄에 달할 수 있으므로 강조된 diff가 길 수 있다는 점을 유의하세요. 먼저 최상위 packages 항목에 집중한 다음 version 필드에 집중하세요. 약 5천 줄을 초과하는 파일에는 같은 엔진으로 큰 JSON 페이로드를 처리하도록 설정된 compare-json 페이지가 더 적합합니다.
caret (^)과 tilde (~) 범위의 차이는 무엇인가요?
둘 다 매니페스트를 수동으로 편집하지 않고 업데이트를 허용하는 semver 범위입니다. caret ^1.2.3은 가장 왼쪽의 0이 아닌 자릿수를 변경하지 않는 어떤 버전이든 허용하므로 1.2.3부터 1.999.999까지 받아들이지만 2.0.0은 받아들이지 않습니다. tilde ~1.2.3은 더 엄격합니다: 패치 업데이트만 허용하므로 1.2.3부터 1.2.999까지 받아들이지만 1.3.0은 받아들이지 않습니다. caret은 npm 기본값이며 더 느슨한 범위입니다. tilde는 라이브러리가 minor 릴리스에서 깨뜨린 이력이 있을 때 손을 뻗는 것입니다.
큰 lockfile에 크기 제한이 있나요?
사실상 있습니다. diff는 브라우저에서 실행되므로 매우 큰 입력 (예를 들어 모노레포의 20,000줄 lockfile)은 메모리에 따라 페이지를 느리게 하거나 탭을 멈추게 할 수 있습니다. 일반적인 앱 매니페스트와 측당 수천 줄까지의 lockfile에서는 diff가 사실상 즉시 완료됩니다. 더 큰 파일에는 compare-json 페이지가 더 나은 진입점입니다. 거대한 lockfile을 정기적으로 비교한다면 로컬에서 git diff package-lock.json을 실행하고 페이저로 파이프하는 것을 고려하세요. 그 워크플로우는 어떤 브라우저 도구보다 더 멀리 확장됩니다.
개인정보 보호 및 작동 방식
매니페스트는 브라우저를 떠나지 않습니다. diff, JSON 파싱, 강조 표시, 렌더링은 모두 당신의 컴퓨터에서 실행됩니다. 우리는 텍스트를 업로드하거나, 로깅하거나, 어떤 제3자 서비스로 전달하지 않습니다. 이것은 독점 코드에 특히 중요합니다: 미출시 라이브러리의 package.json이나 비공개 저장소의 lockfile을 클라우드 서비스에 붙여넣는 것 자체가, 특히 매니페스트가 내부 scoped 패키지, 비공개 registry 호스트, 개발 중인 제품 이름을 명시할 때 고용주의 데이터 처리 정책을 위반할 수 있습니다. 주장 검증은 간단합니다. 브라우저의 DevTools를 열고 Network 탭으로 전환한 다음 두 매니페스트를 붙여넣고 지켜보세요. 비교할 때 외부 요청이 없습니다. 같은 개인정보 보호 모델은 compare-json, pnpm-lock.yaml용 compare-yaml, 일반 코드 검토용 git-diff-online을 포함한 다른 도구 전체에서 유지됩니다. 기본 사양에 대해서는 Yarn의 설정 참조와 npm package.json 문서를 참조하세요.