[node.js] 플러그인에 대해 npm에서 피어 종속성을 사용하는 이유는 무엇입니까?

예를 들어, Grunt 플러그인이 grunt에 대한 종속성을 ” 피어 종속성 ” 으로 정의하는 이유는 무엇 입니까?

플러그인이 grunt-plug / node_modules 에서 자체 종속성으로 Grunt를 가질 수없는 이유는 무엇 입니까?

피어 종속성은 https://nodejs.org/en/blog/npm/peer-dependencies/에 설명되어 있습니다.

그러나 나는 그것을 정말로 얻지 못한다.

현재 Grunt 작업을 사용하여 소스 파일을 / dist / 폴더에 빌드하여 로컬 장치에서 제공하는 AppGyver 스테로이드와 함께 일하고 있습니다. 나는 npm에 아주 새롭고 grunt이므로 무슨 일이 일어나고 있는지 완전히 이해하고 싶습니다.

지금까지 나는 이것을 얻는다 :

[rootfolder] /package.json 은 npm grunt-steroids에게 개발 을 위해 npm 패키지에 의존 한다고 알려줍니다 .

  "devDependencies": {
    "grunt-steroids": "0.x"
  },

괜찮아. [rootfolder] 에서 npm install을 실행 하면 종속성을 감지하고 [rootfolder] / node_modules / grunt-steroids에 grunt-steroids를 설치 합니다.

그런 다음 Npm은 [rootfolder] /node_modules/grunt-steroids/package.json을 읽으 므로 grunt-steroids자체 종속성을 설치할 수 있습니다 .

"devDependencies": {
    "grunt-contrib-nodeunit": "0.3.0",
    "grunt": "0.4.4"
  },
"dependencies": {
    "wrench": "1.5.4",
    "chalk": "0.3.0",
    "xml2js": "0.4.1",
    "lodash": "2.4.1"
  },
"peerDependencies": {
    "grunt": "0.4.4",
    "grunt-contrib-copy": "0.5.0",
    "grunt-contrib-clean": "0.5.0",
    "grunt-contrib-concat": "0.4.0",
    "grunt-contrib-coffee": "0.10.1",
    "grunt-contrib-sass": "0.7.3",
    "grunt-extend-config": "0.9.2"
  },

종속성 “패키지는 [rootfolder] / node_modules / grunt-steroids / node_modules에 설치되어 있으며 이는 나에게 논리적입니다.

devDependencies “가 설치되어 있지 않습니다. 확실하게 npm을 사용하여 감지하려고 시도하고 grunt-steroids개발하지 않는 것으로 감지 됩니다.

그러나 ” peerDependencies “가 있습니다.

이것들은 [rootfolder] / node_modules에 설치되어 있는데 , 다른 root 플러그인 (또는 무엇이든)과의 충돌을 피하기 위해 [rootfolder] / node_modules / grunt-steroids / node_modules에 왜 없는지 이해하지 못 합니까?



답변

TL; DR : [1] peerDependencies 은 노출 되지 않은 “비공개” 종속성 과 달리 소비 코드에 노출되고 사용되는 것으로 예상되는 종속성을위한 것이며 구현 세부 사항 일뿐입니다.

동료 상호 의존성 문제 해결

NPM의 모듈 시스템은 계층 적입니다. 보다 간단한 시나리오의 가장 큰 장점 중 하나는 npm 패키지를 설치할 때 해당 패키지에 자체 종속성이 있으므로 즉시 사용할 수 있다는 것입니다.

그러나 다음과 같은 경우에 문제가 발생합니다.

  • 프로젝트와 사용중인 일부 모듈은 다른 모듈에 따라 다릅니다.
  • 세 개의 모듈은 서로 대화해야합니다.

예에서

하자 당신이 구축하고 말하는 YourCoolProject당신이 모두를 사용 JacksModule 1.0하고 JillsModule 2.0. 그리고에 JacksModule의존 JillsModule하지만 다른 버전에 의존 한다고 가정 해 봅시다 1.0. 이 두 버전이 맞지 않는 한 아무런 문제가 없습니다. 표면 아래에서 JacksModule사용 되는 사실 JillsModule은 구현 세부 사항입니다. 우리는 JillsModule두 번 번들을 제공 하지만 안정적인 소프트웨어를 즉시 얻을 때 지불해야 할 가격은 적습니다.

그러나 이제는 어떤 식 으로든 JacksModule의존성을 드러내면 어떨까요 JillsModule? JillsClass예를 들어 인스턴스를 받아들입니다 . new JillsClass사용 2.0하는 라이브러리 버전 을 만들어 전달하면 jacksFunction어떻게됩니까? 모든 지옥은 풀릴 것이다! 간단한 것을 좋아 jillsObject instanceof JillsClass갑자기 돌아갑니다 false때문에 jillsObject실제의 인스턴스 인 다른 JillsClass2.0버전.

동료 종속성이이를 해결하는 방법

그들은 npm에게 말한다

이 패키지가 필요하지만 내 모듈 전용 버전이 아니라 프로젝트의 일부인 버전이 필요합니다.

NPM이 패키지 프로젝트에 설치되고 있음을 볼 때 하지 않는 그 의존성을 가지고, 또는이가 호환되지 않는 버전 그것의를, 설치 과정에서 사용자에게 경고합니다.

언제 피어 종속성을 사용해야합니까?

  • 당신이 라이브러리를 작성하는 경우 다른 프로젝트에서 사용하고, 수
  • 이 라이브러리는 다른 라이브러리를 사용 하고 있습니다.
  • 사용자가 다른 라이브러리에서도 작업 할 것을 기대 / 필요

일반적인 시나리오는 더 큰 프레임 워크를위한 플러그인입니다. Gulp, Grunt, Babel, Mocha 등을 생각해보십시오. Gulp 플러그인을 작성하는 경우, 플러그인이 개인용 Gulp 버전이 아니라 사용자 프로젝트에서 사용하는 것과 동일한 Gulp에서 작동하기를 원합니다.


주석

  1. 너무 오래; 읽지 않았다. 너무 긴 것으로 간주되는 텍스트에 대한 짧은 요약을 나타내는 데 사용됩니다.

답변

먼저 기사를 다시 읽는 것이 좋습니다. 약간 혼란 스럽지만 winston-mail의 예제는 그 이유를 보여줍니다.

예를 들어, 테스트 된 최신 버전이기 때문에 객체에 winston-mail@0.2.3지정된 "winston": "0.5.x"것으로 가정 해 봅시다 "dependencies". 당신의 최신 버전을 찾아 볼 수 있도록 앱 개발자는 최신의 그리고 최고의 물건을 원 winston하고의를 winston-mail하고로 package.json에 넣어

{
  "dependencies": {
    "winston": "0.6.2",
    "winston-mail": "0.2.3"
  }
}

그러나 이제 npm install을 실행하면 예기치 않은 종속성 그래프가 생성됩니다.

├── winston@0.6.2
└─┬ winston-mail@0.2.3
  └── winston@0.5.11

이 경우 몇 가지 문제가 발생할 수있는 여러 버전의 패키지가있을 수 있습니다. 피어 종속성을 통해 npm 개발자는 사용자에게 루트 폴더에 특정 모듈이 있는지 확인할 수 있습니다. 그러나 특정 버전의 패키지를 설명하면 다른 버전을 사용하는 다른 패키지에 문제가 발생할 수 있다는 점은 정확합니다. 이 문제는 기사에서 알 수 있듯이 npm 개발자와 관련이 있습니다.

한 가지 조언 : 정기적 인 종속성과는 달리 피어 종속성 요구 사항 은 관대해야합니다 . 피어 종속성을 특정 패치 버전으로 잠그면 안됩니다.

따라서 개발자는 peerDependencies 를 정의하기 위해 semver 를 따라야합니다. GitHub에서 grunt-steroids 패키지에 대한 이슈를 열어야합니다.


답변

peerDependencies 가능한 가장 간단한 예제로 설명했습니다.

{
  "name": "myPackage",
  "dependencies": {
    "foo": "^4.0.0",
    "react": "^15.0.0"
  }
}


{
  "name": "foo"
  "peerDependencies": {
    "react": "^16.0.0"
  }
}

이 버전의 반응 설치하려고하기 때문에 오류가 발생합니다 myPackage에에 설치 NPM 실행 ^15.0.0foo반작용 만 호환되는 ^16.0.0.

peerDependencies가 설치되지 않았습니다.


답변