Αρχική
» ΒΑΣΙΚΕΣ ΓΝΩΣΕΙΣ
»
Πώς να διορθώσετε το σφάλμα "Module Not Found: Can’t resolve fs" στο Webpack
Πώς να διορθώσετε το σφάλμα "Module Not Found: Can’t resolve fs" στο Webpack
Τελευταία επαλήθευση: 11 Σεπτεμβρίου 2026. Το σφάλμα “Module not found: Error: Can’t resolve 'fs'” συνήθως σημαίνει ότι το Webpack δημιουργεί κώδικα για browser, αλλά ο πηγαίος κώδικάς σας—ή μία από τις εξαρτήσεις του—εισάγει το module συστήματος αρχείων του Node.js. Το Node τεκμηριώνει το node:fs ως το API για αλληλεπίδραση με το σύστημα αρχείων, ενώ η τρέχουσα τεκμηρίωση του Webpack αναφέρει ότι το Webpack 5 δεν παρέχει πλέον αυτόματα polyfills για τα βασικά modules του Node.js για builds browser.
Το σημαντικό μέρος είναι η επιλογή της διόρθωσης που ταιριάζει με αυτό που ο κώδικας προσπαθεί πραγματικά να κάνει. Δεν υπάρχει μία ρύθμιση που να είναι σωστή για κάθε έργο. Εάν η εφαρμογή σας χρειάζεται πραγματικά να διαβάζει αρχεία από τον δίσκο του διακομιστή, μεταφέρετε αυτήν την εργασία σε κώδικα Node/διακομιστή. Εάν μια εξάρτηση εισάγει το fs μόνο για μια προαιρετική λειτουργία Node-only που το bundle browser σας δεν χρησιμοποιεί ποτέ, το resolve.fallback: { fs: false } μπορεί να είναι κατάλληλο. Εάν το πακέτο έχει μια συμβατή με browser έκδοση, χρησιμοποιήστε αυτήν αντίθετα. Και εάν το bundle προορίζεται να εκτελεστεί σε Node, στοχεύστε το Node αντί να προσποιείστε ότι είναι ένα bundle web.
Πίνακας γρήγορης απόφασης
Κατάσταση
Καλύτερη πρώτη διόρθωση
Κύριο πλεονέκτημα
Κύριο συμβιβασμός
Ο δικός σας κώδικας browser εισάγει το fs
Αφαιρέστε το από τη διαδρομή browser ή μεταφέρετε τη λειτουργία σε διακομιστή/API
Ταιριάζει με τον πραγματικό χρόνο εκτέλεσης
Απαιτεί ένα αρχιτεκτονικό όριο μεταξύ πελάτη και διακομιστή
Μια εξάρτηση εισάγει το fs, αλλά αυτή η λειτουργία δεν χρησιμοποιείται ποτέ στο browser
Εξετάστε το resolve.fallback: { fs: false }
Μικρή, απλή διόρθωση build
Θα αποτύχει λογικά εάν το πακέτο εκτελέσει αργότερα κώδικα που εξαρτάται από το σύστημα αρχείων
Μια εξάρτηση προσφέρει builds για browser και Node
Χρησιμοποιήστε ή αναβαθμίστε στην καταχώρηση συμβατή με browser
Διατηρεί την επιθυμητή συμπεριφορά browser
Μπορεί να απαιτήσει αλλαγές πακέτου/έκδοσης
Η έξοδος εκτελείται σε Node, όχι σε browser
Χρησιμοποιήστε target: "node"
Διατηρεί τα ενσωματωμένα του Node διαθέσιμα κατά τον χρόνο εκτέλεσης
Η έξοδος δεν είναι πλέον bundle browser
Προσπαθείτε να κάνετε “polyfill fs” στο browser
Επαναξιολογήστε την απαίτηση
Αποφεύγει ένα παραπλανητικό στρώμα συμβατότητας
Μπορεί να χρειαστείτε διαφορετική ροή εργασίας αποθήκευσης/αρχείων στο browser
Η επίσημη τεκμηρίωση resolve.fallback του Webpack δηλώνει ότι το Webpack 5 δεν παρέχει πλέον polyfills για τα βασικά modules του Node αυτόματα. Οι σημειώσεις έκδοσης του Webpack 5 εξηγούν τον λόγο: τα αυτόματα polyfills θα μπορούσαν να προσθέσουν μεγάλο, περιττό κώδικα συμβατότητας στα bundles frontend, οπότε το Webpack μετέφερε την ευθύνη στον προγραμματιστή της εφαρμογής ή του πακέτου.
Βήμα 1: Βρείτε ποιος εισάγει το fs
Ξεκινήστε με την πρώτη χρήσιμη γραμμή στην έξοδο σφάλματος του Webpack. Συνήθως δείχνει στο αρχείο όπου απέτυχε η επίλυση, για παράδειγμα:
ERROR in ./src/utils/fileHelper.js 1:0-20
Module not found: Error: Can't resolve 'fs'
Εικονογράφηση παραγόμενη από AI μιας αποτυχίας build του Webpack σε εισαγωγή fs. Δεν είναι έξοδος από πραγματικό έργο· τα ονόματα αρχείων και οι αριθμοί γραμμών είναι ενδεικτικοί.
Εάν το αποτυγχάνον αρχείο είναι δικό σας, αναζητήστε σε αυτό οποιαδήποτε από τις μορφές:
const fs = require('fs')
// ή
import fs from 'node:fs'
// ή
import { readFile } from 'node:fs/promises'
Η επίσημη τεκμηρίωση File System του Node επιβεβαιώνει ότι το node:fs και το node:fs/promises είναι APIs του Node για λειτουργίες συστήματος αρχείων. Ένα κανονικό bundle browser δεν αποκτά πρόσβαση στον δίσκο του διακομιστή απλώς επειδή το Webpack μπορεί να αναλύσει την εισαγωγή.
Εάν το αποτυγχάνον αρχείο βρίσκεται κάτω από το node_modules, μην επεξεργαστείτε αμέσως αυτό το πακέτο επί τόπου. Πρώτα, εντοπίστε ποια εξάρτηση κορυφαίου επιπέδου το έφερε στο bundle browser σας. Η χρήσιμη ερώτηση δεν είναι μόνο “Ποιο πακέτο εισάγει το fs;”, αλλά “Γιατί αυτή η διαδρομή κώδικα προσανατολισμένη στο Node είναι προσβάσιμη από την καταχώρηση πελάτη μου;”
Χρησιμοποιήστε αυτήν τη διάγνωση όταν: το σφάλμα εμφανίζεται μετά από αναβάθμιση του Webpack, προσθήκη εξάρτησης, εισαγωγή μιας προηγούμενης μόνο για διακομιστή βοηθητικής λειτουργίας σε κώδικα frontend, ή μεταφορά κοινού κώδικα σε bundle πελάτη.
Πρακτικός έλεγχος: αφαιρέστε προσωρινά την εισαγωγή που οδηγεί στο αποτυγχάνον module και κάντε ξανά build. Εάν το σφάλμα fs εξαφανιστεί, έχετε επιβεβαιώσει τη διαδρομή εξάρτησης πριν αλλάξετε τη διαμόρφωση του Webpack.
Βήμα 2: Εάν ο κώδικας χρειάζεται πραγματικά πρόσβαση στο σύστημα αρχείων, μεταφέρετέ τον σε κώδικα Node/διακομιστή
Αυτή είναι η καλύτερη διόρθωση όταν ο κώδικας χρειάζεται να διαβάζει αρχεία διαμόρφωσης, πρότυπα, τοπικά έγγραφα, ιδιωτικά κλειδιά, παραγόμενα assets, logs διακομιστή ή οτιδήποτε άλλο από το σύστημα αρχείων της μηχανής.
Για παράδειγμα, αυτό είναι κατάλληλο σε Node:
import { readFile } from 'node:fs/promises'
export async function loadTemplate() {
return readFile('./templates/email.html', 'utf8')
}
Αλλά δεν πρέπει να έλκεται σε μια καταχώρηση browser. Αντίθετα, εκθέστε το αποτέλεσμα μέσω του επιπέδου διακομιστή της εφαρμογής σας. Μια απλοποιημένη διαίρεση θα μπορούσε να είναι:
// κώδικας πλευράς browser
export async function loadTemplate() {
const response = await fetch('/api/template')
if (!response.ok) throw new Error('Failed to load template')
return response.text()
}
Εικονογράφηση παραγόμενη από AI του διαχωρισμού της εργασίας συστήματος αρχείων Node από τον κώδικα browser. Είναι ένα εννοιολογικό παράδειγμα αρχιτεκτονικής, όχι στιγμιότυπο οθόνης συγκεκριμένου framework.
Ο συμβιβασμός είναι αρχιτεκτονικός: προσθέτετε ένα endpoint διακομιστή ή άλλο όριο πλευράς διακομιστή, αλλά διατηρείτε τη σημασιολογία του fs. Το browser ζητά δεδομένα· ο διακομιστής διαβάζει το σύστημα αρχείων.
Αυτή η λύση είναι κατάλληλη όταν: η λειτουργία συστήματος αρχείων είναι πραγματική και απαραίτητη.
Αυτή η λύση δεν είναι απαραίτητη όταν: η εισαγωγή υπάρχει μόνο μέσα σε μια προαιρετική διαδρομή κώδικα Node που το browser δεν εκτελεί ποτέ. Σε αυτήν την περίπτωση, μια καταχώρηση πακέτου συγκεκριμένη για browser ή μια αγνοημένη fallback μπορεί να είναι πιο καθαρή.
Βήμα 3: Χρησιμοποιήστε resolve.fallback: { fs: false } μόνο όταν η συμπεριφορά συστήματος αρχείων είναι προαιρετική
Η επίσημη οδηγία μετανάστευσης του Webpack από την έκδοση 4 στην 5 λέει συγκεκριμένα ότι οι διαμορφώσεις που χρησιμοποιούν το παλιό μοτίβο node.fs: 'empty' πρέπει να μεταβούν σε:
Εικονογράφηση παραγόμενη από AI του resolve.fallback: { fs: false }. Χρησιμοποιήστε το μόνο όταν το browser δεν χρειάζεται τη συμπεριφορά συστήματος αρχείων της εξάρτησης.
Ο ορισμός μιας fallback σε false λέει στο Webpack να μην συμπεριλάβει μια υλοποίηση για αυτό το μη επιλυμένο module. Αυτό μπορεί να είναι ακριβώς σωστό για ένα πακέτο που περιέχει μια προστατευμένη διαδρομή μόνο για Node, όπως κώδικας που χρησιμοποιεί το fs μόνο κατά την απόδοση διακομιστή ή την εκτέλεση CLI.
Μπορεί επίσης να κρύψει το σφάλμα build αφήνοντάς σας με ένα σφάλμα σχεδιασμού χρόνου εκτέλεσης. Θεωρήστε αυτήν την εξάρτηση:
Εάν το browser σας καλεί πραγματικά το loadUserConfig(), η αντικατάσταση του fs με “τίποτα” δεν δημιουργεί ένα λειτουργικό σύστημα αρχείων browser. Το build μπορεί να προχωρήσει, αλλά η λειτουργία δεν μπορεί ακόμα να εκτελέσει την επιθυμητή λειτουργία Node.
Χρησιμοποιήστε fs: false όταν: έχετε επαληθεύσει ότι η διαδρομή συγκεκριμένη για το σύστημα αρχείων δεν χρησιμοποιείται στον στόχο web.
Μην το χρησιμοποιείτε όταν: η λειτουργία browser σας εξαρτάται από το readFileSync, τη διάσχιση καταλόγων, διαδρομές διακομιστή ή άλλη πραγματική συμπεριφορά συστήματος αρχείων Node.
Γιατί το “απλώς εγκαταστήστε ένα polyfill fs” είναι συνήθως η λάθος πρώτη απάντηση
Η τρέχουσα τεκμηρίωση resolve.fallback του Webpack δίνει παραδείγματα χειροκίνητων polyfills για αρκετά βασικά modules του Node όπως path, buffer, stream και crypto. Σημαντικό, η λίστα συμβατότητάς του δεν παρέχει μια γενική αντικατάσταση fs ισοδύναμη με το σύστημα αρχείων του Node.
Αυτή η διαφορά είναι σημαντική. Οι βοηθητικές συναρτήσεις JavaScript μπορούν συχνά να αναπαραχθούν σε ένα browser. Η αυθαίρετη πρόσβαση στο σύστημα αρχείων του host/διακομιστή είναι μια δυνατότητα χρόνου εκτέλεσης, όχι απλώς μια λείπουσα βοηθητική συνάρτηση.
Εάν αυτό που χρειάζεστε πραγματικά είναι μια ροή εργασίας browser, επιλέξτε έναν σχεδιασμό εγγενή στο browser για την συγκεκριμένη εργασία—for παράδειγμα, ανακτήστε ένα asset από ένα URL, αφήστε τον χρήστη να επιλέξει ένα αρχείο ή αποθηκεύστε δεδομένα εφαρμογής χρησιμοποιώντας έναν κατάλληλο μηχανισμό αποθήκευσης browser. Μην κρίνετε την επιτυχία μόνο από το αν το Webpack σταματήσει να εμφανίζει το σφάλμα.
Επιλογή 4: Προτιμήστε μια εξάρτηση συμβατή με browser ή εξαγωγή πακέτου
Εάν το σφάλμα προέρχεται από πακέτο τρίτων, ελέγξτε εάν αυτό το πακέτο υποστηρίζει browsers επίσημα. Ο τρέχων οδηγός exports πακέτων του Webpack εξηγεί ότι τα πακέτα μπορούν να παρέχουν δεσμευτικές εξαγωγές για περιβάλλοντα όπως browser και node. Η καθοδήγηση έκδοσης του Webpack συνιστά επίσης στους δημιουργούς πακέτων να παρέχουν εναλλακτικές συμβατές με frontend όταν οι υλοποιήσεις μόνο για Node δεν είναι κατάλληλες για browsers.
Για παράδειγμα, ένα πακέτο μπορεί εννοιολογικά να εκθέτει:
Εάν μια αναβαθμισμένη έκδοση πακέτου παρέχει μια σωστή καταχώρηση browser ενώ η παλαιότερη έκδοσή σας δεν το κάνει, η αναβάθμιση μπορεί να είναι ασφαλέστερη από τη διαμόρφωση fs: false. Ομοίως, η αντικατάσταση ενός πακέτου προσανατολισμένου στο Node με ένα σχεδιασμένο ρητά για χρήση σε browser μπορεί να μειώσει τα hacks συμβατότητας και την πολυπλοκότητα του bundle.
Επιλέξτε αυτήν τη διαδρομή όταν: η εξάρτηση υποτίθεται ότι λειτουργεί σε browsers, αλλά η εγκατεστημένη έκδοση επιλέγει ή εκθέτει μια υλοποίηση μόνο για Node.
Συμβιβασμός: η αναβάθμιση ή η αντικατάσταση ενός πακέτου μπορεί να εισαγάγει αλλαγές API, οπότε εκτελέστε τις κανονικές δοκιμές της εφαρμογής σας αντί να θεωρείτε μια επιτυχημένη μεταγλώττιση ως επαρκή.
Επιλογή 5: Εάν η έξοδος είναι ένα bundle Node, ορίστε τον στόχο σε Node
Μερικές φορές το Webpack δεν παράγει καθόλου κώδικα browser. Μπορεί να κάνετε bundle ένα CLI, ένα εργαζόμενο παρασκηνίου, ένα εργαλείο build, έναν διακομιστή SSR ή μια υπηρεσία Node. Σε αυτήν την περίπτωση, η προσπάθεια καταστολής του fs είναι ανάποδη: ο χρόνος εκτέλεσης το παρέχει πραγματικά.
μεταγλωττίζει για ένα περιβάλλον παρόμοιο με το Node.js και αφήνει τα ενσωματωμένα modules όπως το fs και το path για το Node να τα παρέχει κατά τον χρόνο εκτέλεσης.
Η πιο λεπτομερής αναφορά διαμόρφωσης target του Webpack διακρίνει επίσης τα web, node, στόχους Electron, εργαζόμενους web και άλλα περιβάλλοντα.
Χρησιμοποιήστε target: 'node' όταν: το παραγόμενο JavaScript θα εκτελεστεί κάτω από το Node.
Μην το χρησιμοποιείτε για να “διορθώσετε” ένα κανονικό SPA browser: η αλλαγή του στόχου δεν κάνει ένα browser να παρέξει ξαφνικά τα APIs συστήματος αρχείων του Node. Αλλάζει το περιβάλλον που το Webpack υποθέτει ότι θα εκτελέσει το bundle.
Προηγμένα builds Node: τα externals μπορούν να κρατήσουν τα ενσωματωμένα στον χρόνο εκτέλεσης
Για bundles διακομιστή, το Webpack παρέχει επίσης συμπεριφορά externals προσανατολισμένη στο Node. Η επίσημη τεκμηρίωση Externals δηλώνει ότι το externalsPresets.node μπορεί να μεταχειρίζεται τα ενσωματωμένα του Node όπως fs, path και vm ως εξωτερικά και να τα φορτώνει με το require() χρόνου εκτέλεσης του Node.
Μια τυπική διαμόρφωση προσανατολισμένη στο Node θα μπορούσε λοιπόν να μοιάζει ως εξής:
Αυτό είναι ένα προηγμένο ζήτημα bundle διακομιστή, όχι ένα workaround browser.
Βήμα 4: Κάντε ξανά build, στη συνέχεια δοκιμάστε τη λειτουργία που προκάλεσε την εισαγωγή
Μετά την πραγματοποίηση της αρχιτεκτονικής ή της αλλαγής διαμόρφωσης, κάντε ξανά build:
npm run build
Εικονογράφηση παραγόμενη από AI μιας επιτυχημένης επαναδημιουργίας του Webpack. Οι αριθμοί εκδόσεων, τα μεγέθη assets και οι χρόνοι build είναι φανταστικά παραδείγματα.
Μια καθαρή μεταγλώττιση αποδεικνύει μόνο ότι η επίλυση module πέτυχε. Δεν αποδεικνύει ότι η επηρεαζόμενη λειτουργία συμπεριφέρεται σωστά. Δοκιμάστε σύμφωνα με τη διόρθωση που επιλέξατε:
Εάν μεταφέρατε την πρόσβαση αρχείων στον διακομιστή, καλέστε τη λειτουργία browser και επαληθεύστε ότι το endpoint διακομιστή επιστρέφει τα αναμενόμενα δεδομένα.
Εάν ορίσατε fs: false, ασκήστε την εξάρτηση στο browser και επιβεβαιώστε ότι δεν εισέρχεται ποτέ στη διαδρομή που εξαρτάται από το σύστημα αρχείων.
Εάν μεταβήκατε σε μια build browser ενός πακέτου, εκτελέστε την πραγματική ροή εργασίας του πακέτου面向 χρήστη.
Εάν αλλάξατε τον στόχο σε Node, εκτελέστε την παραγόμενη έξοδο κάτω από την έκδοση Node που υποστηρίζετε.
Η εφαρμογή σας χρειάζεται πραγματικά δεδομένα συστήματος αρχείων διακομιστή
resolve.fallback.fs = false
Μόνο εάν η διαδρομή fs δεν χρησιμοποιείται
Όχι
Προαιρετική διαδρομή εξάρτησης μόνο για Node
Πακέτο/εξαγωγή συγκεκριμένη για browser
Ναι, εάν το πακέτο το υποστηρίζει
Όχι· παρέχει αντίθετα συμπεριφορά συγκεκριμένη για browser
Μια εξάρτηση προορίζεται να υποστηρίζει και τους δύο χρόνους εκτέλεσης
target: 'node'
Όχι
Ναι
Το bundle εκτελείται πραγματικά σε Node
Γενικό “fs polyfill”
Εξαρτάται από τη βιβλιοθήκη και τη σημασιολογία
Δεν είναι ισοδύναμο με αυθαίρετη πρόσβαση συστήματος αρχείων Node
Μόνο μετά την επαλήθευση της ακριβούς συμπεριφοράς browser που χρειάζεστε
Ειδική περίπτωση: κοινός κώδικας που εισάγεται από bundles browser και διακομιστή
Μια συχνή πηγή αυτού του σφάλματος είναι μια βοηθητική ενότητα που περιέχει τόσο καθαρές συναρτήσεις όσο και βοηθητικές μόνο για Node:
// shared-utils.js
import fs from 'node:fs'
export function formatDate(date) {
return new Intl.DateTimeFormat('en-US').format(date)
}
export function readConfig(path) {
return fs.readFileSync(path, 'utf8')
}
Ακόμα κι αν το browser σας εισάγει μόνο το formatDate, η εισαγωγή fs σε επίπεδο κορυφής μπορεί να αναγκάσει το Webpack να επιλύσει το fs. Ένας πιο καθαρός σχεδιασμός είναι να χωρίσετε τις ενότητες:
// shared/formatDate.js
export function formatDate(date) {
return new Intl.DateTimeFormat('en-US').format(date)
}
// server/readConfig.js
import fs from 'node:fs'
export function readConfig(path) {
return fs.readFileSync(path, 'utf8')
}
Αυτό κάνει το όριο χρόνου εκτέλεσης ορατό στο γράφημα ενοτήτων αντί να εξαρτάται από tree-shaking ή μια fallback για να αφαιρέσει μια μη συμβατή εισαγωγή.
Ειδική περίπτωση: το σφάλμα εμφανίστηκε μετά την αναβάθμιση από το Webpack 4
Αυτό είναι ένα από τα κλασικά συμπτώματα μετανάστευσης στο Webpack 5. Το Webpack 4 παρείχε αυτόματα shims συμβατότητας για πολλά βασικά modules του Node. Το Webpack 5 σταμάτησε σκόπιμα να το κάνει αυτό. Εάν ο κώδικάς σας “δούλευε πριν την αναβάθμιση”, ρωτήστε αν χρειαζόταν πραγματικά τη λειτουργία Node στο browser ή αν ο παλαιός bundler εισήγαγε σιωπηλά κώδικα συμβατότητας.
Η επίσημη οδηγός μετανάστευσης του Webpack συνιστά την ανάγνωση της καθοδήγησης για αλλαγές που σπάνε τη συμβατότητα στο σφάλμα build και την αντικατάσταση της παλιάς διαμόρφωσης συμβατότητας node.* με τη νεότερη προσέγγιση resolver όπου είναι κατάλληλο.
Μην υποθέτετε ότι η αναδημιουργία κάθε polyfill του Webpack 4 είναι η καλύτερη μετανάστευση. Οι σημειώσεις έκδοσης του Webpack συνιστούν modules συμβατά με frontend όπου είναι δυνατόν.
Τελικός αυτοέλεγχος
Πριν κλείσετε το ζήτημα, επαληθεύστε τα ακόλουθα σημεία:
Βρείτε το ακριβές αρχείο πηγής ή την εξάρτηση που εισάγει το fs.
Επιβεβαιώστε εάν το επηρεαζόμενο bundle εκτελείται σε browser ή σε Node.
Εάν είναι bundle browser, επαληθεύστε εάν η λειτουργία χρειάζεται πραγματικά συμπεριφορά συστήματος αρχείων.
Εάν το χρειάζεται, μεταφέρετε τη λειτουργία συστήματος αρχείων πίσω από ένα όριο διακομιστή.
Εάν η χρήση του fs από την εξάρτηση είναι προαιρετική και δεν εκτελείται ποτέ στο browser, εξετάστε το resolve.fallback: { fs: false }.
Εάν το πακέτο παρέχει επίσημα μια εξαγωγή browser, προτιμήστε αυτήν αντί να καταστείλετε απαιτούμενη συμπεριφορά.
Εάν το bundle εκτελείται σε Node, χρησιμοποιήστε έναν στόχο Node αντί για έναν στόχο web.
Κάντε ξανά build και επιβεβαιώστε ότι το σφάλμα επίλυσης module έχει εξαφανιστεί.
Εκτελέστε την πραγματική λειτουργία που προηγουμένως έλκε το fs· μην σταματήσετε στο “μεταγλωττίστηκε επιτυχώς”.
Η μόνιμη διόρθωση είναι να ευθυγραμμίσετε τον κώδικα με τον χρόνο εκτέλεσής του. Το fs ανήκει στο περιβάλλον συστήματος αρχείων του Node. Το Webpack 5 κάνει αυτό το όριο πιο ορατό μη εισάγοντας πλέον αυτόματα polyfills βασικών modules του Node. Μόλις αποφασίσετε εάν η εργασία συστήματος αρχείων ανήκει στον διακομιστή, είναι προαιρετική στο browser ή είναι μέρος ενός bundle με στόχο το Node, η σωστή διαμόρφωση γίνεται πολύ πιο εύκολη στην επιλογή.