오래된 npm 패키지 대량 업데이트

한동안 손대지 않은 프로젝트로 돌아와서 업데이트하고 싶은 오래된 npm 패키지가 많이 있다는 것을 알게 된 적이 있습니까? 이것은 내가 때때로 나 자신을 발견하는 상황이며 그것을 해결할 좋은 방법을 생각해 본 적이 없습니다.

오래된 패키지 찾기



먼저, 오래된 것이 무엇인지 어떻게 알 수 있습니까? 이를 위해 npm outdated 을 사용할 수 있으며 다음과 같이 반환됩니다.



더 많은 정보가 필요한 경우 --long 플래그를 제공하고 패키지가 dependencies 또는 devDependencies 목록에 있는지 여부와 같은 추가 출력을 얻을 수 있습니다.



업데이트가 package.json 에 있는 semver 필터 내에 있으면 npm upgrade 으로 쉽게 업그레이드할 수 있지만 위 목록에서 내가 찾은 것과 같은 상황에 처한 경우 주요 버전 업그레이드가 많이 있습니다. 완료해야 하며 허용된 semver 범위를 벗어나기 때문에 비스타터입니다.

SemVer 범위를 넘어 업그레이드



허용된 semver 범위를 넘어 업그레이드하려면 어떻게 해야 합니까? 새 설치로 취급하고 다음과 같이 @latest 태그(또는 특정 버전)를 지정합니다.

npm install typescript@latest


이렇게 하면 주요 버전 "업그레이드"인 최신 버전의 TypeScript(작성 당시 4.1.2)가 설치되며 업그레이드할 패키지가 한두 개뿐인 경우 충분히 쉽게 수행할 수 있지만 저는 내 리포지토리에서 업그레이드할 19개의 패키지를 살펴보고 있으므로 많은 복사/붙여넣기가 필요합니다.

출력에서 업그레이드


npm outdated 명령에 대해 주목할 가치가 있는 것은 --json를 전달하면 사람이 읽을 수 있는 것이 아니라 JSON 출력을 반환한다는 것입니다.

JSON이 있는 경우 jq 을 사용하여 JSON을 조작하고 명령줄에서 실행할 명령을 작성할 수 있습니다.
npm outdated --json --long의 출력 JSON은 다음과 같습니다.

{
    "@types/istanbul-lib-report": {
        "current": "1.1.1",
        "wanted": "1.1.1",
        "latest": "3.0.0",
        "location": "node_modules/@types/istanbul-lib-report",
        "type": "devDependencies",
        "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped#readme"
    }
}


개체로 시작하지만 각 하위 개체를 데이터 세트에서 별도의 노드로 취급하고 to_entities 를 사용하여 배열로 변환하여 다음과 같은 새로운 출력을 제공합니다.

[
    {
        "key": "@types/istanbul-lib-report",
        "value": {
            "current": "1.1.1",
            "wanted": "1.1.1",
            "latest": "3.0.0",
            "location": "node_modules/@types/istanbul-lib-report",
            "type": "devDependencies",
            "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped#readme"
        }
    }
]


이것은 key가 패키지 이름이고 value가 패키지 업그레이드에 대한 정보인 사전을 제공합니다. 이제 배열이므로 원하는 휴리스틱을 사용하여 필터링하도록 선택할 수 있으며 잠시 동안 dependencies 에서 별도로 devDependencies 를 업그레이드합니다. jq에서 select 함수를 사용하여 이를 수행합니다.

npm outdated --json --long | jq 'to_entries | .[] | select(.value.type == "devDependencies")'


The select function allows you to do whatever filtering you want, for example if you wanted to only update the TypeScript type definitions you could change the select to be select(.key | startswith("@types")).



이를 실행하면 select 조건과 일치하는 패키지만 표시되는 필터링된 출력이 터미널에 제공됩니다. 마지막 단계는 새 패키지 설치 버전을 생성하는 것입니다.

npm outdated --json --long | jq 'to_entries | .[] | select(.value.type == "devDependencies") | .key + "@latest"'


이 업데이트는 @latest 태그를 지정했지만 더 엄격한 semver 고정을 위해 특정 버전을 설치하려는 경우 .key + "@" + .value.latest를 사용할 수 있습니다. 이제 터미널의 출력은 다음과 같습니다.

"@types/istanbul-lib-report@latest"


남은 일은 패키지를 npm install 로 전달하는 것이므로 출력을 파이프할 수 있다고 생각할 수 있습니다.

npm outdated --json --long | jq 'to_entries | .[] | select(.value.type == "devDependencies") | .key + "@latest"' | npm install


안타깝게도 npm install는 표준 입력에서 제공하는 명령줄 인수를 허용하지 않으므로 대신 xargs 을 사용하여 표준 입력을 명령줄 인수로 변환합니다.

npm outdated --json --long | jq 'to_entries | .[] | select(.value.type == "devDependencies") | .key + "@latest"' | xargs npm install


이것으로 업그레이드가 완전히 진행되었습니다!

결론



한동안 작업하지 않은 프로젝트로 돌아올 때 이 스니펫을 편리하게 보관할 것입니다. 많은 수의 업데이트를 수행하는 쉬운 방법이기 때문입니다.

볼 수 있는 다른 옵션은 npm-check-updates 입니다. 이는 위와 유사한 방식으로 업데이트되지만 업데이트를 제어하는 ​​방법에 대한 다른 기능도 있는 명령줄 유틸리티입니다.

좋은 웹페이지 즐겨찾기