Kezdőlap
» Alap tudás
»
Hogyan javítsd meg a „Module Not Found: Can’t Resolve fs” hibát Webpackben
Hogyan javítsd meg a „Module Not Found: Can’t Resolve fs” hibát Webpackben
Utolsó ellenőrzés: 2026. szeptember 11. A „Module not found: Error: Can’t resolve 'fs'” hiba általában azt jelenti, hogy a Webpack böngészőnek fordít kódot, de a forráskódod – vagy egyik függősége – importálja a Node.js fájlrendszer modulját. A Node dokumentációja a node:fs-t írja le mint a fájlrendszerrel való interakció API-ját, míg a Webpack aktuális dokumentációja szerint a Webpack 5 már nem automatikusan polyfill-eli a Node.js core moduljait böngésző buildjeihez.
A lényeg, hogy olyan javítást válassz, amely megfelel annak, amit a kód valójában próbál csinálni. Nincs egyetlen beállítás, amely minden projekt esetén helyes lenne. Ha az alkalmazásodnak valóban szüksége van fájlok olvasására a szerver lemezéről, helyezd át ezt a munkát Node/szerver kódra. Ha egy függőség csak egy opcionális, kizárólag Node-specifikus funkció miatt importálja az fs-t, amelyet a böngésző bundle soha nem használ, akkor a resolve.fallback: { fs: false } lehet a megfelelő. Ha a csomag rendelkezik böngészőkompatibilis builddel, használd azt. Ha pedig a bundle Node-ban fut, célozd meg a Node-ot ahelyett, hogy úgy tennél, mintha web bundle lenne.
Gyors döntési táblázat
Helyzet
Legjobb első javítás
Fő előny
Fő kompromisszum
A saját böngészőkódod importálja az fs-t
Távolítsd el a böngésző útvonalról, vagy helyezd át a műveletet szerverre/API-ra
Megfelel a tényleges futásidejű környezetnek
Architekturális határt igényel a kliens és a szerver között
Egy függőség importálja az fs-t, de ez a funkció soha nem használt a böngészőben
Vizsgáld meg a resolve.fallback: { fs: false } beállítást
Kis, egyszerű build javítás
Logikai hibát okoz, ha a csomag később fájlrendszer-függő kódot hajt végre
Egy függőség böngésző és Node buildet is kínál
Használd vagy frissíts a böngészőkompatibilis belépési pontra
Megőrzi a szándékolt böngésző viselkedést
Csomag/verzió változásokat igényelhet
A kimenet Node-ban fut, nem böngészőben
Használd a target: "node" beállítást
Biztosítja a Node beépített moduljainak elérhetőségét futásidőben
A kimenet már nem böngésző bundle
Próbálod „polyfill-ezni” az fs-t a böngészőben
Gondold át újra a követelményt
Kerüli a félrevezető kompatibilitási réteget
Lehet, hogy más böngészőoldali tárolási/fájl munkafolyamatra van szükséged
A Webpack hivatalos resolve.fallback dokumentációja kimondja, hogy a Webpack 5 már nem polyfill-eli automatikusan a Node core modulokat. A Webpack 5 kiadási jegyzetei elmagyarázzák az okot: az automatikus polyfill-ek nagy, felesleges kompatibilitási kódot adhattak a frontend bundle-ekhez, így a Webpack az alkalmazásra vagy a csomag szerzőjére ruházta ezt a felelősséget.
1. lépés: Derítsd ki, ki importálja az fs-t
Kezdd a Webpack hiba kimenetének első hasznos sorával. Ez általában arra a fájlra mutat, ahol a feloldás sikertelen volt, például:
ERROR in ./src/utils/fileHelper.js 1:0-20
Module not found: Error: Can't resolve 'fs'
AI-generált illusztráció egy Webpack buildről, amely az fs importnál bukik el. Ez nem valós projekt kimenete; a fájlnevek és sorszámok szemléltető jellegűek.
Ha a hibás fájl a tiéd, keresd meg benne bármelyik formát:
const fs = require('fs')
// vagy
import fs from 'node:fs'
// vagy
import { readFile } from 'node:fs/promises'
A Node hivatalos File System dokumentációja megerősíti, hogy a node:fs és a node:fs/promises Node API-k a fájlrendszer műveletekhez. Egy normál böngésző bundle nem kap hozzáférést a szerver lemezéhez csak azért, mert a Webpack képes feldolgozni az importot.
Ha a hibás fájl a node_modules alatt van, ne azonnal szerkeszd azt a csomagot a helyén. Először azonosítsd, melyik felső szintű függőség hozta be a böngésző bundle-edbe. A hasznos kérdés nem csak az, hogy „Melyik csomag importálja az fs-t?”, hanem az is, hogy „Miért érhető el ez a Node-orientált kódútvonal az ügyfél belépési pontomból?”
Használd ezt a diagnosztikát, amikor: a hiba a Webpack frissítése, egy függőség hozzáadása, egy korábban csak szerveroldali segédeszköz frontend kódba importálása, vagy közös kód áthelyezése egy kliens bundle-be után jelenik meg.
Gyakorlati ellenőrzés: ideiglenesen távolítsd el azt az importot, amely a hibás modulhoz vezet, és építsd újra. Ha az fs hiba eltűnik, megerősítetted a függőségi útvonalat, mielőtt megváltoztatnád a Webpack konfigurációját.
2. lépés: Ha a kódnak valóban szüksége van fájlrendszer-hozzáférésre, helyezd át Node/szerver kódra
Ez a legjobb javítás, amikor a kódnak konfigurációs fájlokat, sablonokat, helyi dokumentumokat, privát kulcsokat, generált eszközöket, szerver naplókat vagy bármi mást kell olvasnia a gép fájlrendszeréből.
Például ez helyes Node-ban:
import { readFile } from 'node:fs/promises'
export async function loadTemplate() {
return readFile('./templates/email.html', 'utf8')
}
De ezt nem kellene behúzni egy böngésző belépési pontba. Ehelyett tedd közzé az eredményt az alkalmazásod szerver rétegén keresztül. Egy egyszerűsített felosztás így nézhet ki:
// browser-side code
export async function loadTemplate() {
const response = await fetch('/api/template')
if (!response.ok) throw new Error('Failed to load template')
return response.text()
}
AI-generált illusztráció a Node fájlrendszer munkájának elkülönítéséről a böngészőkódtól. Ez egy koncepcionális architektúra példa, nem egy konkrét keretrendszer képernyőképe.
A kompromisszum architektúrális: hozzáadsz egy szerver végpontot vagy egy másik szerveroldali határt, de megőrzöd az fs szemantikáját. A böngésző adatokat kér; a szerver olvassa a fájlrendszert.
Ez a megoldás akkor megfelelő, amikor: a fájlrendszer művelet valós és szükséges.
Ez a megoldás nem szükséges, amikor: az import csak egy opcionális Node kódútvonalon belül létezik, amelyet a böngésző soha nem hajt végre. Ebben az esetben egy böngésző-specifikus csomag belépési pont vagy egy figyelmen kívül hagyott fallback tisztább lehet.
3. lépés: Használd a resolve.fallback: { fs: false } beállítást csak akkor, ha a fájlrendszer viselkedés opcionális
A Webpack hivatalos Webpack 4-ről 5-re való migrációs útmutatója kifejezetten azt mondja, hogy a régi node.fs: 'empty' mintát használó konfigurációknak át kell térniük a következőre:
AI-generált illusztráció a resolve.fallback: { fs: false } beállításról. Ezt csak akkor használd, ha a böngészőnek nincs szüksége a függőség fájlrendszer viselkedésére.
A fallback false-ra állítása azt mondja a Webpacknek, hogy ne foglaljon magába implementációt az adott fel nem oldott modulhoz. Ez pontosan megfelelő lehet egy olyan csomaghoz, amely egy védett, csak Node-ra vonatkozó ágat tartalmaz, például olyan kódot, amely az fs-t csak szerveroldali renderelés vagy CLI végrehajtás során használja.
Ez elrejtheti a build hibát, miközben egy futásidejű tervezési hibát hagyhat. Gondold végig ezt a függőséget:
Ha a böngésződ valóban meghívja a loadUserConfig()-ot, az fs „semmire” cserélése nem hoz létre működő böngésző fájlrendszert. A build folytatódhat, de a funkció továbbra sem tudja elvégezni a szándékolt Node műveletet.
Használd az fs: false beállítást, amikor: ellenőrizted, hogy a fájlrendszer-specifikus ág nem használt a web célban.
Ne használd, amikor: a böngésző funkciója függ a readFileSync-tól, könyvtár bejárásától, szerver útvonalaktól vagy más valós Node fájlrendszer viselkedéstől.
Miért a „csak telepíts egy fs polyfill-t” általában a rossz első válasz
A Webpack aktuális resolve.fallback dokumentációja példákat ad kézi polyfill-ekre több Node core modulhoz, mint például a path, buffer, stream és crypto. Figyelemre méltó, hogy a kompatibilitási listája nem biztosít általános fs helyettesítőt, amely egyenértékű lenne a Node fájlrendszerrel.
Ez a különbség fontos. A JavaScript segédeszközöket gyakran újra lehet létrehozni a böngészőben. A gazda/szerver fájlrendszeréhez való tetszőleges hozzáférés egy futásidejű képesség, nem csak egy hiányzó segédfüggvény.
Ha valóban böngésző munkafolyamatra van szükséged, válassz böngésző-natív tervezést a konkrét feladathoz – például tölts le egy eszközt URL-ről, hagyd, hogy a felhasználó válasszon fájlt, vagy tárolj alkalmazásadatokat egy megfelelő böngésző tárolási mechanizmussal. Ne csak azt ítéld meg, hogy a Webpack abbahagyta-e a hiba megjelenítését.
4. opció: Válassz böngészőkompatibilis függőséget vagy csomag exportot
Ha a hiba egy harmadik féltől származó csomagból származik, vizsgáld meg, hogy a csomag hivatalosan támogatja-e a böngészőket. A Webpack aktuális csomag exports útmutatója elmagyarázza, hogy a csomagok feltételes exportokat biztosíthatnak olyan környezetekhez, mint a browser és a node. A Webpack kiadási útmutatása azt is javasolja, hogy a csomag szerzői biztosítsanak frontend-kompatibilis alternatívákat, amikor a csak Node implementációk nem alkalmasak böngészőkhöz.
Például egy csomag koncepcionálisan így exporthat:
Ha egy frissített csomagverzió megfelelő böngésző belépési pontot biztosít, míg a régebbi verziód nem, a frissítés biztonságosabb lehet, mint az fs: false konfigurálása. Hasonlóképpen, egy Node-orientált csomag cseréje egy kifejezetten böngésző használatra tervezett csomagra csökkentheti a kompatibilitási hackeket és a bundle komplexitását.
Válaszd ezt az utat, amikor: a függőségnek böngészőkben kellene működnie, de a telepített verzió egy csak Node implementációt választ vagy exponál.
Kompromisszum: egy csomag frissítése vagy cseréje API változásokat vezethet be, ezért futtasd a normál alkalmazás tesztjeidet, ahelyett, hogy a sikeres fordítást elegendőnek tekintenéd.
5. opció: Ha a kimenet egy Node bundle, állítsd a célt Node-ra
Néha a Webpack egyáltalán nem böngésző kódot állít elő. Lehet, hogy egy CLI-t, háttér munkást, build eszközt, SSR szervert vagy Node szolgáltatást bundle-elsz. Ebben az esetben az fs elfojtása próbálkozás visszafelé megy: a futásidejű környezet valóban biztosítja azt.
Node.js-szerű környezetre fordít, és a beépített modulokat, mint például az fs és a path, a Node-ra bízza futásidőben.
A Webpack részletesebb target konfigurációs referenciája megkülönbözteti a web, node, Electron célokat, web worker-eket és más környezeteket.
Használd a target: 'node' beállítást, amikor: a keletkező JavaScript Node alatt fog végrehajtódni.
Ne használd egy normál böngésző SPA „javítására”: a cél megváltoztatása nem teszi azt, hogy a böngésző hirtelen biztosítsa a Node fájlrendszer API-jait. Megváltoztatja azt a környezetet, amelyet a Webpack feltételez a bundle végrehajtásához.
Haladó Node buildek: az externals futásidőben tarthatja a beépített modulokat
Szerver bundle-ekhez a Webpack Node-orientált externals viselkedést is biztosít. A hivatalos Externals dokumentáció kimondja, hogy az externalsPresets.node kezelheti a Node beépített moduljait, mint például az fs, path és vm, külsőként, és betöltheti őket a Node futásidejű require()-jával.
Egy tipikus Node-orientált konfiguráció tehát így nézhet ki:
Ez egy haladó szerver-bundle kérdés, nem egy böngésző workaround.
4. lépés: Építsd újra, majd teszteld azt a funkciót, amely az importot okozta
Az architektúrális vagy konfigurációs változás elvégzése után építsd újra:
npm run build
AI-generált illusztráció egy sikeres Webpack újraépítésről. A verziószámok, eszköz méretek és build idők fikciós példák.
A tiszta fordítás csak azt bizonyítja, hogy a modul feloldása sikerült. Nem bizonyítja, hogy az érintett funkció helyesen viselkedik. Teszteld a választott javításnak megfelelően:
Ha a fájl hozzáférést a szerverre helyezted át, hívd meg a böngésző funkciót, és ellenőrizd, hogy a szerver végpont a várt adatokat adja-e vissza.
Ha beállítottad az fs: false-t, gyakorold a függőséget a böngészőben, és erősítsd meg, hogy soha nem lép be a fájlrendszer-függő ágba.
Ha egy csomag böngésző buildjére váltottál, futtasd a csomag valódi felhasználó felé irányuló munkafolyamatát.
Ha a célt Node-ra változtattad, futtasd a lefordított kimenetet a támogatott Node verzió alatt.
Gyakori javítások összehasonlítása
Javítás
Böngészőbiztos?
Megőrzi a valódi Node fájlrendszer hozzáférést?
Mikor válaszd
Helyezd át az fs munkát szerverre/API-ra
Igen
Igen, a szerveren
Az alkalmazásodnak valóban szüksége van szerver fájlrendszer adatokra
resolve.fallback.fs = false
Csak akkor, ha az fs ág nem használt
Nem
Opcionális, csak Node függőségi útvonal
Böngésző-specifikus csomag/export
Igen, ha a csomag támogatja
Nem; helyette böngésző-specifikus viselkedést biztosít
A függőségnek mindkét futásidejű környezetet támogatnia kell
target: 'node'
Nem
Igen
A bundle valóban Node-ban fut
Általános „fs polyfill”
Függ a könyvtártól és a szemantikától
Nem egyenértékű a tetszőleges Node fájlrendszer hozzáféréssel
Csak az után, hogy ellenőrizted a pontos böngésző viselkedést, amelyre szükséged van
Speciális eset: közös kód, amelyet mind a böngésző, mind a szerver bundle importál
Ennek a hibának egy gyakori forrása egy segédeszköz modul, amely tartalmaz mind tiszta függvényeket, mind csak Node segédeszközöket:
// 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')
}
Még ha a böngésződ csak a formatDate-ot importálja is, a felső szintű fs import kényszerítheti a Webpacket az fs feloldására. Egy tisztább tervezés a modulok felosztása:
// 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')
}
Ez láthatóvá teszi a futásidejű határt a modul gráfban, ahelyett, hogy a tree-shakingre vagy egy fallbackre támaszkodna egy inkompatibilis import eltávolításához.
Speciális eset: a hiba a Webpack 4-ről való frissítés után jelent meg
Ez az egyik klasszikus Webpack 5 migrációs tünet. A Webpack 4 automatikusan biztosított kompatibilitási shimeket sok Node core modulhoz. A Webpack 5 szándékosan abbahagyta ezt. Ha a kódod „a frissítés előtt működött”, kérdezd meg, hogy valóban szüksége volt-e a Node funkcióra a böngészőben, vagy a régi bundler csendben injektált kompatibilitási kódot.
A hivatalos Webpack migrációs útmutató azt javasolja, hogy olvasd el a build hiba törő változtatási útmutatását, és cseréld le a régi node.* kompatibilitási konfigurációt az újabb resolver megközelítésre, ahol megfelelő.
Ne feltételezd, hogy minden Webpack 4 polyfill újra létrehozása a legjobb migráció. A Webpack saját kiadási jegyzetei frontend-kompatibilis modulokat javasolnak, ahol lehetséges.
Végső önellenőrzés
Mielőtt lezárnád az ügyet, ellenőrizd ezeket a pontokat:
Találd meg a pontos forrásfájlt vagy függőséget, amely importálja az fs-t.
Erősítsd meg, hogy az érintett bundle böngészőben vagy Node-ban fut-e.
Ha ez egy böngésző bundle, ellenőrizd, hogy a funkció valóban igényel-e fájlrendszer viselkedést.
Ha igen, helyezd át a fájlrendszer műveletet egy szerver határ mögé.
Ha a függőség fs használata opcionális és soha nem hajtódik végre a böngészőben, fontold meg a resolve.fallback: { fs: false } beállítást.
Ha a csomag hivatalosan biztosít böngésző exportot, válaszd azt a szükséges viselkedés elfojtása helyett.
Ha a bundle Node-ban hajtódik végre, használj Node célt a web cél helyett.
Építsd újra, és erősítsd meg, hogy a modul-feloldási hiba eltűnt.
Futtasd azt a valódi funkciót, amely korábban behúzta az fs-t; ne állj meg a „sikeresen lefordítva” ponton.
A tartós javítás az, hogy igazítsd a kódot a futásidejű környezetéhez. Az fs a Node fájlrendszer környezetéhez tartozik. A Webpack 5 láthatóbbá teszi ezt a határt azzal, hogy már nem injektál automatikusan Node core polyfill-eket. Miután eldöntötted, hogy a fájlrendszer munka a szerverre tartozik, opcionális a böngészőben, vagy része egy Node-célú bundle-nek, a helyes konfiguráció kiválasztása sokkal könnyebbé válik.