javascript - Vad gör npm install --legacy-peer-deps exakt? När rekommenderas det/Vad är ett potentiellt användningsfall?


Sprang precis på detta fel:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email 
npm ERR! Found: [email 
npm ERR! node_modules/react
npm ERR!   react@"17.0.1" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.0" from [email 
npm ERR! node_modules/react-hook-mousetrap
npm ERR!   react-hook-mousetrap@"*" from the root project
npm ERR! 

Modulen jag försöker installera verkar ha ett annat peer-beroende än det jag har installerat. Det verkar som att npm ändrade sitt beteende i detta avseende och nu låter installationen misslyckas.

Vad kan jag göra nu för att fixa detta? Jag vill inte nedgradera min React-version för detta.

Jag vet att det finns en flagga som heter --legacy-peer-deps, men jag är inte säker på vad den exakt gör och huruvida det rekommenderas att använda den/vilka potentiella nackdelar det finns? Jag antar att det finns en anledning till att npm lät installationen misslyckas.

Det är bara konstigt eftersom jag använde yarn fram till väldigt nyligen och allt var bra.

Svar #1

Sammanfattning:

  • NPM v7+ installerar peerDependencies som standard; detta är inte fallet med tidigare versioner av NPM.
  • NPM-moduler måste namnge specifika versioner av sina peerDependencies
  • Om du redan har ett peerDependency installerat, men inte med en version som anges av modulen, kommer NPM v7+ att kasta ett fel
  • Att lägga till --legacy-peer-deps ignorerar detta nya krav, på bekostnad av att införa brytande förändringar

--legacy-peer-deps återställer peerDependency-installationsbeteendet från NPM v4 till v6

Ett sätt att tänka på denna flagga är att den inte gör något nytt; snarare säger den till NPM att inte göra något nytt, eftersom NPM v7 nu installerar peerDependencies som standard.

I många fall leder detta till versionskonflikter, vilket kommer att bryta installationsprocessen.

Flaggan --legacy-peer-deps introducerades med v7 som ett sätt att kringgå automatisk installation av peerDependencies; den talar om för NPM att ignorera peer deps och fortsätta med installationen ändå. Så här var det med NPM v4 till v6.

Om du är osäker på skillnaden mellan vanliga deps och peer deps, här är lite bakgrund:

Beroenden vs peerDependencies

Beroenden: Bibliotek eller moduler som ett NPM-modul behöver för att fungera i produktion. (Exempel: Jag byggde nyligen ett bibliotek för att skapa cirkeldiagram som använder Chance.js för att beräkna slumpmässiga tal inom ett angivet intervall; Chance är därför ett beroende för mitt modul.)

peerDependencies: Ett peer dependency är en specifik version eller uppsättning av versioner av ett tredjepartsprogramvarubibliotek som en modul är designad för att fungera med. De är liknande i koncept med relationen mellan en webbläsartillägg och en webbläsare. (Exempel: react-redux har två ganska logiska peerDependencies: react och redux.)

Detta problem drivs delvis av React v17+

På grund av det stora antalet moduler som inte specifikt har lagt till React v17 (eller mer nyligen, React 18) som en peerDependency är det nu vanligt att stöta på felet unable to resolve dependency tree när man kör npm-installationer i en v17 React-applikation.

Detta fel kommer att uppstå när en modul (eller någon av dess egna beroenden) listar en tidigare huvudversion av React som peerDependency utan att specifikt inkludera React v17 också.

(Observera: Liknande beteende kommer att förekomma vid större versionsuppdateringar av vilket annat ramverk eller bibliotek som helst.)

Hur man kontrollerar peerDependencies för en given modul

NPM listar inte peer-dependencies på sidorna för en viss modul. Det finns dock en enkel lösning för att kontrollera peer-dependencies, antingen före eller efter installation. Kör helt enkelt:

npm info name-of-module peerDependencies

Detta kommando kommer att returnera namnet på varje peerDependency tillsammans med alla kompatibla version(er).

Svar #2

Så här löste jag detta problem:

Först, vad som händer: react-hook-mousetrap letar efter [email , men den hittar det inte. Istället hittar den @react17.0.1, som är en nyare version. Av någon anledning gillar inte mousetrap denna nyare version, och du blir meddelad om det (det är inget stort problem, men de bestämde att det var värt att stoppa din build).

En lösning: tvinga installation av den specifika versionen av react som mousetrap vill ha:

yarn add [email 

Detta gör att din React-version rullas tillbaka till en något äldre version som är kompatibel med Mousetrap. Du kommer inte att märka någon skillnad, och i framtida iterationer förhoppningsvis uppdateras Mousetrap, så detta försvinner.

En annan lösning: fatta ett omfattande beslut att inte installera några äldre versionsberoenden:

npm add xxxx --legacy-peer-deps

Vad detta gör är att ignorera gamla beroenden för detta paket. Det är mer omfattande och tar många av besluten åt dig.

Svar #3

legacy-peer-deps:

  • Standard: falsk
  • Typ: Boolean

Får npm att helt ignorera peerDependencies när den bygger ett paketträd, som i npm versionerna 3 till 6.

Om ett paket inte kan installeras på grund av alltför strikta peerDependencies som kolliderar, erbjuder det ett sätt att gå vidare med att lösa situationen.

Detta skiljer sig från --omit=peer, i det att --omit=peer kommer att undvika att packa upp peerDependencies på disken, men kommer fortfarande att utforma ett träd så att peerDependencies kan packas upp på en korrekt plats.

Användning av legacy-peer-deps rekommenderas inte, eftersom det inte kommer att upprätthålla peerDependencies-kontraktet som metaberoenden kan vara beroende av.


Om du vill fortsätta använda legacy-peer-deps utan att behöva lägga till flaggan i varje kommando, kan du konfigurera det i din .npmrc (antingen på projektnivå eller globalt på din dator):

echo "legacy-peer-deps=true" >> .npmrc

npmrc :

npm hämtar sina konfigurationsinställningar från kommandoraden, miljövariabler och npmrc-filer.

Kommandot npm config kan användas för att uppdatera och redigera innehållet i användar- och globala npmrc-filer.

Relaterade artiklar