Peer Dependencies
- projekt – twój projekt
- projekt nadrzędny – projekt, który ma twój projekt jako zależność
Peer dependencies to są zależności, które przez projekt są wymagane, jednak za samą ich instalację odpowiedzialny jest projekt nadrzędny (czyli ten, który taki projekt zainstaluje).
{
"name": "projekt",
"version": "1.0.0",
"peerDependencies": {
"react": "^17.0.0"
}
}
Projekt nadrzędny:
{
"name": "projekt_nadrzędny",
"dependencies": {
"projekt": "1.0.0",
"react": "17.1.0"
}
}
Definiując peer dependency trzeba wskazać z jaką wersją jest kompatybilny. Projekt nadrzędny, będzie musiał dopilnować, żeby zainstalować odpowiednią wersję (zgodnie z semver).
npm
od wersji 7.x
automatycznie instaluje peer dependencies, jeśli nie są one zdefiniowane w zależności projektu, więc nie dostaniesz automatycznie błędu. Jednak gdy spróbujesz zainstalować inną zależność w wersji, która konfliktuje z automatycznie zainstalowanymi zależnościami, otrzymasz błąd, a instalacja nie zostanie dokończona.
Jednak w niektórych przypadkach npm
najpierw wyświetli ostrzeżenie, a dopiero przy kolejnej instalacji rzuci błędem. Robi to wyłącznie dla twojej wygody ponieważ najpierw doda taką zależność do package.json
, a później z poziomu tego pliku możesz poprawić wersje konfliktujących zależności.
Przykładowo gdy w projekcie masz wyłącznie react-router
to react
zostanie zainstalowany automatycznie.
{
"name": "projekt_nadrzedny",
"version": "1.0.0",
"dependencies": {
"react-router": "^7.4.0"
}
}
Gdy dodasz react
w niekompatybilnej wersji z react-router
to zobaczysz ostrzeżenie jednak react
zostanie dodany do package.json
.
npm i react@16
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: projekt_nadrzedny@1.0.0
npm warn Found: react@19.0.0
npm warn node_modules/react
npm warn peer react@">=18" from react-router@7.4.0
npm warn node_modules/react-router
npm warn react-router@"^7.4.0" from the root project
npm warn 1 more (the root project)
npm warn
npm warn Could not resolve dependency:
npm warn peer react@">=18" from react-router@7.4.0
npm warn node_modules/react-router
npm warn react-router@"^7.4.0" from the root project
{
"name": "projekt_nadrzedny",
"dependencies": {
"react": "^16.14.0",
"react-router": "^7.4.0"
}
}
Gdy uruchomisz instalację jeszcze raz to ujrzysz błąd:
npm i
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: react-router@7.4.0
npm error Found: react@16.14.0
npm error node_modules/react
npm error react@"^16.14.0" from the root project
npm error
npm error Could not resolve dependency:
npm error peer react@">=18" from react-router@7.4.0
npm error node_modules/react-router
npm error react-router@"^7.4.0" from the root project
npm error
npm error Conflicting peer dependency: react@19.0.0
npm error node_modules/react
npm error peer react@">=18" from react-router@7.4.0
npm error node_modules/react-router
npm error react-router@"^7.4.0" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
Dzięki temu w pliku będziesz mieć możliwość poprawy wersji i zainstalowania zależności jeszcze raz. Przykładowo:
npm i react@18
removed 3 packages, changed 1 package, and audited 20 packages in 618ms
3 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Korzyści definiowania peer dependencies
- Mniejsze
node_modules
– Projekt nie duplikuje zależności, a korzysta z wersji zainstalowanej przez projekt nadrzędny. Oszczędza to miejsce na dysku i przyspiesza instalację projektów nadrzędnych. - Lżejszy kod produkcyjny – Projekty korzystają z tych samych zależności co pozytywne wpływa na rozmiar i wydajność. Dodatkowo gdyby zbudowany projekt zawierałby dwie instancje tej samej zależności jednak w różnych wersjach to mogłoby to prowadzić do błędów na produkcji – czasem ciężkich do zdiagnozowania.
- Jasna zdefiniowana kompatybilność – Gdy projekt nadrzędny nie będzie posiadał kompatybilnych zależności to
npm
wyświetli błąd. Pozwala to na szybką reakcję i aktualizację projektu.
Kiedy używać?
W skrócie dla projektów, które mogą być zależnościami. Będąc bardziej specyficznym to projekty które nadbudowują funkcjonalności innych projektów lub powstają na ich podstawie. Na przykład:
- Biblioteki UI – material-ui, Vuetify.
- Pluginy dla Webpack, Babel, ESLint.
- Narzędzia takie jak react-router czy @testing-library/react.
- Frameworki takie jak Next.js, Nuxt.
Peer Dependencies Metadata
W package.json
znajdziesz również peerDependenciesMeta
. To pole pozwala przekazać dodatkowe informacje o peer dependencies. Obecnie dostępna jest opcja optional
, która jak sama nazwa mówi, sprawi, że zależność nie będzie wymagana oraz nie będzie instalowana automatycznie przez npm
.
Idealnym przykładem jest tutaj typescript
, który może być wykorzystywany przez projekt, jednak sam w sobie nie musi być potrzebny do działania w przypadku wielu projektów nadrzędnych.
{
"name": "your_project",
"peerDependencies": {
"react": "^18.0.0",
"typescript": "^3.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
}
Przykład użycia peerDependenciesMeta
przez Vuetify.