NodeJS 프로젝트의 PeerDependencies는 무엇입니까?

10807 단어 nodenpmjavascript
다음과 같이 터미널에서 PeerDependency 경고를 받았을 때 적어도 나에게 혼란을 야기한 용어 중 하나인 PeerDependencies:



Recent happenings about a malicious code attack in a node package는 PeerDependencies의 주제를 많이 포함하고 있어 PeerDependencies가 작동하는 방식에 대한 심층 조사를 시작하기 위해 마침내 이 주제에 대해 궁금해졌습니다. 이 블로그 게시물에서는 이 주제를 더 잘 이해하는 데 도움이 될 수 있는 방식으로 NodeJS PeerDependencies에 대해 알아낸 내용을 기록하겠습니다.

물론 Google을 사용하여 "What are peer dependencies"를 검색하면 일부 결과가 반환됩니다. 그럼에도 불구하고 Google이 반환한 주요 참고 자료 중 어느 것도 내가 만족하는 방식으로 PeerDependencies를 이해하지 못했습니다. 얼마 후 나는 Stackoverflow Page에 대한 훌륭한 PeerDependency 설명을 포함하여 이것을 발견했습니다. 그의 설명은 내가 PeerDependencies의 기본 사항을 이해하고 상상의 "아하!"순간 (Stijn에게 감사합니다!). 그러나 어쨌든 그리고 나는 시각적 학습 유형에 더 가깝기 때문에 Stijn의 "텍스트 기반"Stackoverflow 설명은 PeerDependencies를 이해하는 측면에서 나에게 상상의 마지막 마일 만족을 가져오지 못했습니다. 결과적으로 나는 그의 설명 주위에 몇 가지 코드를 그렸고(아래 인용된 것을 볼 수 있음) 갑자기 상황이 더 명확해졌습니다.

스테인 드 비트 뭐가 문제 야?



선행: 다음 예에서 JillsModule는 프로세스의 까다로운 부분(이후 PeerDependency)이 됩니다. 그래서 사용할 때 가상 버전 추가(@1.0, @2.0)를 추가했습니다.

Let's say we are building OurCoolProject and are using JacksModule and [email protected]. Also let's suppose that JacksModule also depends on JillsModule, but on a different version, say [email protected]. As long as those 2 versions don't meet, there is no problem. The fact that JacksModule is using JillsModule below the surface is just an implementation detail. We are bundling JillsModule (as the code uses 2 different versions, but not related to each other (!)) twice, but that's a small price to pay when we get stable software out of the box.



코드에서 이것은 다음과 같은 것을 의미합니다.

// OurCoolProcject.js

import JacksModule from 'jacksmodule';
import JillsModule(@2.0) from 'jillsmodule(@2.0)';

const OurCoolProcject = () => {
    // do some stuff with JacksModule
    // do some stuff with JillsModule(@2.0). stuff won't break as we have the compatible @2.0 version of JillsModule available in this scope.
}

export default OurCoolProject;



// jacksmodule.js (an npm module)

import JillsModule(@1.0) from 'jillsmodule(@1.0)';

const JacksModule = () => {
    // do some stuff with JillsModule(@1.0). stuff won't break as we have the compatible @1.0 version of JillsModule available in this scope.
}

export default JacksModule;


그러나 다음으로 이 종속 관계는 더욱 까다로워집니다.

Now let's suppose that JacksModule exposes its dependency on JillsModule in some way. It accepts an object instanceof JillsClass for example... What happens when we create a new JillsClass using version 2.0 of the library and pass it along to jacksFunction (that excepts the 1.0 version as we know!)? All hell will break loose! Simple things like jillsObject instanceof JillsClass will suddenly return false, because jillsObject is actually an instance of another JillsClass, the 2.0 version.



코드에서 이것은 다음과 같은 것을 의미합니다.

// OurCoolProcject.js

import jacksFunction from 'jacksmodule';
import JillsModule(@2.0) from 'jillsmodule(@2.0)'; // node resolves to OUR dependency of JillsModule which is 2.0!

const OurCoolProcject = () => {    
    const jillsObject = new JillsModule(@2.0).JillsClass;

    // next the beginning of all evil, we'll pass a jillsObject of version 2.0
    // to jacksFunction (that would expect jillsObject of version 1.0 🤦‍♀️)
    jacksFunction(jillsObject); 
}

export default OurCoolProject;



// jacksmodule.js (an npm module)

import JillsModule(@1.0) from 'jillsmodule(@1.0)';

const jacksFunction = (jillsObject) => {
    // make sure jillsObject is compatible for further usage in this function
    const jillsObjectRocks = jillsObject instanceOf JillsModule(@1.0).JillsClass;
            // └─> 🔥🔥🔥 `jillsObjectRocks` will be a big, fat FALSE
            // as the JillsModule dependencies actively used in this function and
            // passed to this function differ in versions (1.0 vs. 2.0) 🤦‍♀️
    ...
}

export default jacksFunction;


여기서 무슨 일이 일어나고 있는지 알아차리셨나요? jacksFunction는 객체가 JillsModule(1.0)이 아니라 JillsModule(2.0)에서 생성되었기 때문에 호환되지 않음jillsObject을 수신합니다JacksModule. 지금까지 이것은 최악의 경우 작동하지 않는 소프트웨어로 이어지는 문제만을 보여줍니다.

PeerDependencies가 이 문제를 해결하는 방법



운 좋게도 npm에는 이 문제를 해결하려는 내장 지능이 있습니다. JacksModule이 JillsModule(@1.0)을 PeerDependency로 선언하면 npm은 프로젝트의 종속성을 설치할 때 사용자에게 경고할 수 있습니다. 따라서 JacksModulepackage.json에는 다음 선언이 포함되어야 합니다.

{
  "name": "JacksModule",
  ...
  "peerDependencies": {
    "JillsModule": "1.x"
  },
  ...
}


따라서 npm의 PeerDepenedency 인텔리전스는 기본적으로 개발자에게 다음과 같은 경고를 표시하는 콘솔 출력을 트리거합니다.

"이봐, 여기는 JacksModule입니다. 말씀드리겠습니다. JillsModule의 이 특정 패키지가 필요하지만 JacksModule 프로젝트의 일부이고 내 package.json 파일에 나열된 버전이 정말 필요합니다. 따라서 설치되었는지 확인하십시오. 응용 프로그램의 다른 위치에 자신의 용도로 설치했을 수 있는 JillsModule의 다른 버전이 아닌지 확인하십시오."

따라서 결국에는 PeerDependencies가 필요한 npm 패키지에 따라 이를 더 생각하는 것이 까다로울 수 있습니다. 애플리케이션에서 분리된 사용을 위해 새 버전의 패키지 X가 필요한 경우 애플리케이션에서 사용하는 다른 종속성이 패키지 X의 다른 버전에 대한 PeerDependency를 갖는 경우 문제가 발생할 수 있습니다. 이 팝업이 나타나면 - 최악의 경우 또한 소프트웨어에 문제가 발생합니다. 사용할 패키지를 결정하거나 모든 요구 사항을 충족하기 위해 리팩토링이 필요한 코드를 스스로 결정해야 합니다.

이러한 설명과 코드 예제가 귀하에게 적합하고 PeerDependencies에 대한 마지막 생각의 격차가 해소되기를 바랍니다. 질문이 있거나 문서 최적화를 제안하고 싶다면 언제든지 저에게 연락하거나 의견을 남겨주세요.

이 게시물은 이었습니다.

좋은 웹페이지 즐겨찾기