Αρχική
» ΒΑΣΙΚΕΣ ΓΝΩΣΕΙΣ
»
Πώς να διορθώσετε τη σύγκρουση Peer Dependency με τον κωδικό npm ERR! ERESOLVE
Πώς να διορθώσετε τη σύγκρουση Peer Dependency με τον κωδικό npm ERR! ERESOLVE
Εκτελείτε npm install, περιμένετε το npm να προσθέσει ένα πακέτο, και αντί αυτού λαμβάνετε μια οθόνη γεμάτη εξόδους που καταλήγει σε npm ERR! code ERESOLVE και «unable to resolve dependency tree». Η σημαντική ερώτηση δεν είναι «Πώς κάνω το npm να σταματήσει να παραπονιέται;». Είναι «Ποιες δύο απαιτήσεις έκδοσης δεν μπορούν να ισχύουν ταυτόχρονα;»
Αυτή η διάκριση καθορίζει αν θα καταλήξετε με μια σταθερή διόρθωση ή απλώς θα αναγκάσετε το npm να εγκαταστήσει ένα δέντρο εξαρτήσεων που ένα από τα πακέτα σας δηλώνει ρητά ότι δεν υποστηρίζει.
Σημείωση έκδοσης: όπως ελέγχθηκε στις 11 Σεπτεμβρίου 2026, η τεκμηρίωση του npm χαρακτηρίζει το npm CLI 12.0.2 ως την πιο πρόσφατη έκδοση τεκμηρίωσης. Το npm εγκαθιστά αυτόματα τα peerDependencies από προεπιλογή από την έκδοση npm 7, και οι συγκρουόμενες απαιτήσεις peer μπορούν να προκαλέσουν αποτυχία εγκατάστασης όταν το npm δεν μπορεί να κατασκευήσει ένα έγκυρο δέντρο. Δείτε την τεκμηρίωση package.json του npm.
Οι χρήσιμες γραμμές σε μια αναφορά ERESOLVE είναι η έκδοση που βρήκε το npm και το μη συμβατό εύρος peer που ζητείται από ένα άλλο πακέτο.
Τι σημαίνει πραγματικά το ERESOLVE;
Άμεση απάντηση: το npm βρήκε απαιτήσεις εξαρτήσεων που δεν μπορούν να ικανοποιηθούν ταυτόχρονα υπό το τρέχον δέντρο εξαρτήσεων.
Μια peer dependency είναι ένα συμβόλαιο συμβατότητας. Ένα plugin ή ένα συνοδευτικό πακέτο μπορεί να δηλώσει ότι αναμένει από το έργο σας να παρέχει μια συμβατή έκδοση ενός άλλου πακέτου. Για παράδειγμα, ένα plugin μπορεί να δηλώσει:
{
"peerDependencies": {
"react": "^17.0.0"
}
}
Αν το έργο σας απαιτεί React 18 και αυτό το plugin δηλώνει συμβατότητα μόνο με React 17, το npm έχει αποδείξεις ότι ο ζητούμενος συνδυασμός μπορεί να μην υποστηρίζεται. Το πακέτο μπορεί τυχαία να λειτουργεί με React 18, αλλά το npm δεν μπορεί να υποθέσει ότι ο συγγραφέας του πακέτου προόριζε αυτή τη συμβατότητα.
Η ίδια η τεκμηρίωση του npm συμβουλεύει τους συγγραφείς πακέτων να κρατούν τα εύρη peer dependency όσο πιο ευρέα επιτρέπει η δοκιμασμένη συμβατότητά τους, επειδή τα υπερβολικά στενά εύρη peer μπορούν να δημιουργήσουν συγκρούσεις. Αυτό δεν σημαίνει ότι οι καταναλωτές πρέπει απλώς να αγνοούν κάθε εύρος που δεν τους αρέσει.
Ποιο πακέτο προκαλεί πραγματικά τη σύγκρουση;
Διαβάστε την αναφορά ERESOLVE πριν αλλάξετε οτιδήποτε. Αναζητήστε δύο μέρη:
Found: η έκδοση που έχει ήδη επιλεγεί ή ζητηθεί από το ριζικό σας έργο.
Could not resolve dependency / peer: το πακέτο που απαιτεί διαφορετικό εύρος.
Σε ένα απλοποιημένο παράδειγμα, το npm μπορεί να αναφέρει ότι το ριζικό σας έργο χρησιμοποιεί react@18.3.0, ενώ το some-package@2.1.0 απαιτεί react@^16.8.0 || ^17.0.0. Η σύγκρουση δεν είναι «npm εναντίον React». Είναι η ασυμβατότητα μεταξύ της επιλεγμένης έκδοσης React σας και του εύρους peer που δηλώνεται από το some-package.
Καταγράψτε τρεις τιμές πριν επεξεργαστείτε το package.json: το πακέτο υποδοχής, το πακέτο σε σύγκρουση και το εύρος peer που αναμένει.
Χρειάζεται να επιθεωρήσω πρώτα το δέντρο εξαρτήσεων;
Ναι, ειδικά όταν το πακέτο σε σύγκρουση δεν είναι άμεση εξάρτηση. Το npm παρέχει δύο χρήσιμες εντολές για διαφορετικές προβολές του δέντρου.
npm ls react --all
npm explain some-package
Η εντολή npm ls εκτυπώνει το λογικό δέντρο εξαρτήσεων και μπορεί να εντοπίσει μη έγκυρα ή ελλιπή πακέτα. Η εντολή npm explain, διαθέσιμη επίσης ως npm why, δείχνει την αλυσίδα εξαρτήσεων που προκάλεσε την εγκατάσταση ενός πακέτου. Δείτε την τεκμηρίωση npm ls και την τεκμηρίωση npm explain.
Μπορείτε επίσης να επιθεωρήσετε τα μεταδεδομένα του registry για μια υποψήφια έκδοση πακέτου:
Η εντολή npm view διαβάζει τα μεταδεδομένα του πακέτου από το registry, επιτρέποντάς σας να συγκρίνετε αν μια νεότερη ή παλαιότερη έκδοση υποστηρίζει την έκδοση υποδοχής που χρησιμοποιείτε ήδη. Δείτε την τεκμηρίωση npm view.
Μια χρήσιμη σειρά αποφάσεων είναι να εντοπίσετε τις συγκρουόμενες εκδόσεις, να τις ευθυγραμμίσετε σκόπιμα και μόνο τότε να εξετάσετε τις σημαίες παράκαμψης.
Μπορώ να το διορθώσω εγκαθιστώντας μια συμβατή έκδοση πακέτου;
Συνήθως, αυτή είναι η καλύτερη διόρθωση. Βρείτε μια τομή μεταξύ της έκδοσης υποδοχής που χρειάζεται η εφαρμογή σας και του εύρους peer που υποστηρίζεται από το plugin.
Αν μια νεότερη έκδοση του some-package δηλώνει συμβατότητα με React 18, ενημερώστε αυτό το πακέτο:
npm install some-package@latest
Αν η εφαρμογή σας δεν χρειάζεται React 18 και το plugin είναι σημαντικό, η αντίθετη επιλογή μπορεί να είναι ασφαλέστερη: εγκαταστήστε μια έκδοση React που πραγματικά ικανοποιεί το τεκμηριωμένο εύρος peer του plugin.
Η σωστή κατεύθυνση εξαρτάται από την εφαρμογή σας. Μην υποβαθμίζετε αυτόματα ένα framework μόνο για να διατηρήσετε ένα εγκαταλελειμμένο plugin, και μην αναβαθμίζετε αυτόματα ένα plugin σε μια μεγάλη έκδοση χωρίς να διαβάσετε τις σημειώσεις μετανάστευσής του.
Πρέπει να επεξεργαστώ πρώτα το package.json ή να διαγράψω πρώτα το node_modules;
Διορθώστε πρώτα την απόφαση έκδοσης. Η διαγραφή του node_modules δεν αλλάζει ένα μη συμβατό εύρος peer.
Μόλις το package.json περιγράφει ένα συμβατό σύνολο άμεσων εξαρτήσεων, εκτελέστε μια κανονική εγκατάσταση ώστε το npm να ενημερώσει το αρχείο κλειδώματος:
npm install
Αν αναδομείτε σκόπιμα μια παλιά τοπική εγκατάσταση μετά τη διόρθωση των δηλώσεων, η αφαίρεση του node_modules μπορεί να βοηθήσει να διασφαλιστεί ότι η επόμενη εγκατάσταση είναι καθαρή. Αλλά η διαγραφή αρχείων χωρίς αλλαγή των μη συμβατών απαιτήσεων απλώς ζητά από το npm να ανακαλύψει ξανά την ίδια σύγκρουση.
Ομοίως, η εκκαθάριση της cache του npm δεν είναι κανονικό φάρμακο για μια σημασιολογική σύγκρουση peer dependency. Μια αναφορά ERESOLVE που ονομάζει μη συμβατά εύρη εκδόσεων σας λέει ήδη τι κατηγορία προβλήματος έχετε.
Η ευθυγράμμιση εκδόσεων πρέπει να προηγείται των workaround· η εκκαθάριση cache δεν κάνει τα μη συμβατά εύρη peer συμβατά.
Πότε πρέπει να χρησιμοποιήσω overrides στο package.json;
Χρησιμοποιήστε τα overrides όταν χρειάζεστε σκόπιμα να αλλάξετε το τι επιλύει μια υπάρχουσα ακμή εξάρτησης, συνήθως για μια μεταβατική εξάρτηση. Το npm τεκμηριώνει τα overrides ως μηχανισμό ριζικού έργου για την αντικατάσταση εκδόσεων εξαρτήσεων, τον περιορισμό ενός μεταβατικού πακέτου ή την υποκατάσταση ενός fork.
Μην αντιμετωπίζετε τα overrides ως μια γενική εντολή για να δηλώσετε ότι ένα μη συμβατό συμβόλαιο peer είναι μαγικά έγκυρο. Αν το πραγματικό πρόβλημα είναι ότι ένα πακέτο τρίτων έχει λανθασμένα ή υπερβολικά στενά μεταδεδομένα εξαρτήσεων, επαληθεύστε ότι ο κώδικας είναι συμβατός και προτιμήστε μια διορθωμένη έκδοση upstream όταν είναι διαθέσιμη.
Η τεκμηρίωση του npm 12 περιγράφει επίσης τα packageExtensions, τα οποία μπορούν να προσθέσουν ή να διορθώσουν μεταδεδομένα εξαρτήσεων τρίτων—συμπεριλαμβανομένων των ευρών peer dependency—από το ριζικό έργο ενώ περιμένετε μια διόρθωση upstream. Αυτό είναι ένα προηγμένο εργαλείο επειδή αναλαμβάνετε την ευθύνη για τα διορθωμένα μεταδεδομένα. Δείτε την τεκμηρίωση npm package.json: overrides και packageExtensions.
Πρέπει να χρησιμοποιήσω το --legacy-peer-deps;
Χρησιμοποιήστε το μόνο όταν χρειάζεστε σκόπιμα μια προσωρινή έξοδο διαφυγής συμβατότητας.
npm install --legacy-peer-deps
Το npm τεκμηριώνει το legacy-peer-deps ως αιτία για το npm να αγνοεί τις peer dependencies κατά την κατασκευή του δέντρου πακέτων, παρόμοια με τη συμπεριφορά του npm 3 έως το npm 6. Το npm δηλώνει ρητά ότι η χρήση του είναι μη συνιστώμενη επειδή δεν επιβάλλει το συμβόλαιο peer dependency στο οποίο μπορεί να βασίζονται τα πακέτα. Δείτε την τεκμηρίωση διαμόρφωσης του npm.
Αυτή η σημαία μπορεί να είναι λογική όταν έχετε δοκιμάσει ανεξάρτητα τον συνδυασμό, είστε μπλοκαρισμένοι από ένα υπερβολικά περιοριστικό εύρος peer upstream και χρειάζεστε μια βραχυπρόθεσμη λύση ενώ αντικαθιστάτε ή ενημερώνετε το πακέτο. Είναι μια κακή προεπιλογή για κάθε αποτυχημένη εγκατάσταση.
Είναι το --force το ίδιο πράγμα;
Όχι. Το --force είναι ευρύτερο και πιο επιθετικό.
npm install --force
Το npm δηλώνει ότι το force αφαιρεί πολλές προστασίες και, μεταξύ άλλων επιπτώσεων, επιτρέπει τη εγκατάσταση συγκρουόμενων peer dependencies στο ριζικό έργο. Η τεκμηρίωση του npm προειδοποιεί κατά της χρήσης του όταν δεν κατανοείτε σαφώς τη συνέπεια. Δείτε την τεκμηρίωση npm config: force.
Αν ο μόνος σας στόχος είναι να παρακάμψετε προσωρινά την επιβολή peer dependency, το --legacy-peer-deps είναι πιο στενό στην πρόθεση. Καμία από τις δύο σημαίες δεν αποδεικνύει ότι η προκύπτουσα εφαρμογή είναι συμβατή.
Γιατί αποτυγχάνει το npm ci αφού δούλεψε το npm install;
Ελέγξτε πώς δημιουργήθηκε το αρχείο κλειδώματος. Το npm τεκμηριώνει ότι το npm ci εκτελεί μια παγωμένη καθαρή εγκατάσταση: απαιτεί ένα υπάρχον package-lock.json, αρνείται να το ενημερώσει και εξέρχεται αν το αρχείο κλειδώματος δεν ταιριάζει με το package.json.
Υπάρχει μια επιπλέον λεπτομέρεια peer-dependency: αν το αρχείο κλειδώματος δημιουργήθηκε με μια σημαία διαμόρφωσης δέντρου όπως το --legacy-peer-deps, το npm λέει ότι πρέπει να περάσετε την ίδια ρύθμιση στο npm ci ή μπορεί να αντιμετωπίσετε σφάλματα. Το npm προτείνει την αποθήκευση της ρύθμισης στο .npmrc του έργου όταν αυτή η συμπεριφορά είναι σκόπιμα μέρος του repository:
npm config set legacy-peer-deps=true --location=project
Στη συνέχεια, κάντε commit στο .npmrc του έργου μόνο αν αυτή η παράκαμψη είναι μια σκόπιμη απόφαση της ομάδας—όχι επειδή ένας προγραμματιστής χρειάστηκε μια εντολή διάσωσης μιας χρήσης. Δείτε την τεκμηρίωση npm ci.
Τι γίνεται αν συντηρώ το πακέτο που δηλώνει την peer dependency;
Δοκιμάστε τις εκδόσεις υποδοχής που υποστηρίζετε πραγματικά, στη συνέχεια δηλώστε το ευρύτερο ακριβές εύρος. Το npm προειδοποιεί συγκεκριμένα τους συγγραφείς πακέτων κατά των περιττά στενών προδιαγραφών peer dependency επειδή αυξάνουν την πιθανότητα plugins που είναι αλλιώς συμβατά να μην μπορούν να εγκατασταθούν μαζί.
Αν ένα plugin λειτουργεί σε όλο το React 18.x, για παράδειγμα, ένα εύρος που δεσμεύει περιττά μια έκδοση patch δυσκολεύει τη ζωή των καταναλωτών. Από την άλλη πλευρά, το διευρύνει ένα εύρος χωρίς δοκιμές απλώς μεταφέρει τον κίνδυνο από τον χρόνο εγκατάστασης στον χρόνο εκτέλεσης.
Μια πρακτική ακολουθία επισκευής
Διαβάστε την έξοδο ERESOLVE και γράψτε την έκδοση που βρέθηκε, το πακέτο σε σύγκρουση και το εύρος peer.
Εκτελέστε npm ls <host-package> --all και npm explain <conflicting-package>.
Χρησιμοποιήστε το npm view για να συγκρίνετε τις απαιτήσεις peer των διαθέσιμων εκδόσεων πακέτων.
Επιλέξτε έναν συνδυασμό εκδόσεων των οποίων τα δηλωμένα εύρη επικαλύπτονται πραγματικά.
Ενημερώστε το package.json μέσω npm install package@version ή μια ισοδύναμη σκόπιμη επεξεργασία ακολουθούμενη από npm install.
Χρησιμοποιήστε overrides ή packageExtensions μόνο όταν η μεταβατική εξάρτηση ή τα μεταδεδομένα απαιτούν πραγματικά παρέμβαση σε επίπεδο έργου.
Χρησιμοποιήστε --legacy-peer-deps μόνο ως τεκμηριωμένη προσωρινή εξαίρεση· επιφυλάξτε το --force για περιπτώσεις όπου κατανοείτε πλήρως ποια προστασία απενεργοποιείτε.
Μια επιτυχημένη εγκατάσταση είναι μόνο το ενδιάμεσο σημείο· ο τελικός έλεγχος είναι αν το επιλυμένο δέντρο εξαρτήσεων, η δόμηση, οι δοκιμές και η καθαρή εγκατάσταση επιτυγχάνουν όλα.
Πώς επαληθεύω ότι η σύγκρουση έχει πραγματικά διορθωθεί;
Μην σταματάτε όταν το npm install επιστρέφει κωδικό εξόδου 0. Επαληθεύστε το δέντρο εξαρτήσεων και την εφαρμογή.
npm ls
npm test
npm run build
Χρησιμοποιήστε τα πραγματικά σενάρια δοκιμής και δόμησης του έργου· δεν ορίζει κάθε repository τις ακριβείς εντολές παραπάνω. Αν το repository έχει αρχείο κλειδώματος, δοκιμάστε επίσης μια παγωμένη καθαρή εγκατάσταση:
npm ci
Ένα ισχυρό αποτέλεσμα έχει τέσσερις ιδιότητες:
Το npm install επιτυγχάνει χωρίς σύγκρουση ERESOLVE.
Το npm ls δεν αναφέρει τα σχετικά πακέτα ως μη έγκυρα ή ελλιπή.
Οι δοκιμές σας και η παραγωγική δόμηση περνούν με τις επιλυμένες εκδόσεις.
Το npm ci επιτυγχάνει σε ένα καθαρό περιβάλλον χρησιμοποιώντας το δεσμευμένο αρχείο κλειδώματος και τη διαμόρφωση του έργου.
Αν μπορείτε να ικανοποιήσετε μόνο την πρώτη συνθήκη χρησιμοποιώντας --force, η σύγκρουση εξαρτήσεων δεν έχει πραγματικά επιλυθεί—έχετε δώσει εντολή στο npm να την αποδεχτεί. Αυτό μπορεί να είναι μια συνειδητή βραχυπρόθεσμη απόφαση, αλλά πρέπει να καταγραφεί ως τεχνικό χρέος με το μη συμβατό πακέτο και την προοριζόμενη διαδρομή αντικατάστασης ή αναβάθμισης να προσδιορίζονται σαφώς.