Kezdőlap
» Alap tudás
»
Az „ERR_MODULE_NOT_FOUND” hiba javítása a Node.js ESM importálásokban
Az „ERR_MODULE_NOT_FOUND” hiba javítása a Node.js ESM importálásokban
ERR_MODULE_NOT_FOUNDimportazt jelenti, hogy a Node.js elérte az ECMAScript modul betöltőjét, és nem tudta feloldani a , vagy a program belépési pontja által kért modult import(). A jelenlegi Node.js dokumentációban ez a hiba kifejezetten ESM betöltő feloldási hibaként van definiálva; az ehhez hasonló CommonJS hiba a MODULE_NOT_FOUND. Lásd a hivatalos Node.js hibareferenciát .
A leggyorsabb megoldás az, ha a hiba típusának azonosításával próbálkozunk, mielőtt bármit is megváltoztatnánk. Egy relatív importálás, mint például a , ./utils/logger.jsmás szabályokat követ, mint egy csomagimportálás, mint például a . A Node.js ESM a CommonJS-től eltérően oldja meg a problémát: a relatív importálásokhoz explicit fájlkiterjesztésekre van szükség, és a könyvtárindexeket nem találja el automatikusan a rendszer. Ezek a különbségek számos hibát magyaráznak a -ról a -ra lodashvaló áttérés után .require()import
Pontosan mit nem talál a Node.js?
Kezd a hiba első sorával, ne a teljes veremkövetéssel. Ez általában mind a feloldatlan célt, mind az importálni próbált fájlt is megmutatja. Osztályozd a hibás specifikátort az alábbi csoportok egyikébe:
Relatív fájl:./utils/logger.js vagy ../config.js.
Abszolút fájl vagy fájl URL: abszolút elérési út vagy file:URL.
Csupasz csomag:lodash , express, vagy @scope/pkg.
Csomag alútvonala:some-package/feature.js .
Csomag importálási álnév: egy belső specifikátor, amely -val kezdődik #, és -on keresztül van definiálva package.json"imports".
Először az első hibasort olvasd el: ez a példa egy csupasz csomagnevet azonosít, így a következő ellenőrzéseknek a függőségek telepítésére és a csomagok feloldására kell összpontosítaniuk.
A hivatalos Node.js ECMAScript modulok dokumentációja elkülöníti a relatív, a csupasz és az abszolút specifikátorokat, mivel ezek nem ugyanúgy oldják fel a hibát. Ha már tudod, melyik kategória hibázott, kerüld a véletlenszerű javításokat, például a törlést node_modulesvagy a módosítást package.json, amíg a bizonyítékok nem mutatnak rá.
Egy helyi ESM import tartalmazza a valódi fájlkiterjesztést?
Relatív és abszolút ESM specifikátorok esetén a Node.js megköveteli a fájlkiterjesztést. Sikertelen relatív importálás után nem keres .js, .mjs, vagy karaktereket. A jelenlegi Node.js dokumentáció ezt a szabályt kötelező fájlkiterjesztésnek nevezi , és azt is kimondja, hogy a könyvtárindexeket teljes mértékben meg kell adni..json
Ha a lemezen lévő fájl src/utils/logger.js, akkor ez a biztonságos ESM formátum:
import { logger } from './utils/logger.js';
Nem:
import { logger } from './utils/logger';
A Node.js ESM nem végez kiterjesztéskeresést relatív importálások esetén. Írd be a tényleges fájlkiterjesztést a modulspecifikátorba.
Ez az egyik legfontosabb különbség a CommonJS felbontáshoz képest. A hivatalos Node.js csomag dokumentációja elmagyarázza, hogy require()a Node.js képes kiterjesztések és mappák keresésére, míg az ESM betöltő nem végez kiterjesztéskeresést.
Könyvtárat importálsz egy tényleges fájl helyett?
Egy CommonJS projekt esetleg egy könyvtárimportálásra támaszkodott, amely végül betöltött egy index.js. Ne feltételezze, hogy az ESM betöltő ugyanezt fogja tenni. Ha a struktúrája:
src/
config/
index.js
app.js
előnyben részesítjük:
import config from './config/index.js';
ahelyett, hogy:
import config from './config';
A helyi feloldási hiba általában a pontos feloldatlan elérési útra mutat. Ellenőrizze az elérési utat, a kiterjesztést, és azt, hogy az importálás egy könyvtárat céloz-e meg fájl helyett.
A hivatalos ESM dokumentáció kimondja, hogy az olyan könyvtárindexeket, mint a , ./startup/index.jsteljesen meg kell adni. Ha a kiterjesztés hozzáadása továbbra sem sikerül, hasonlítsa össze az összes elérési út szegmenst a tényleges könyvtárfával.
Valóban ESM-ként fut a projekt?
A Node.js mind a CommonJS, mind az ECMAScript modulokat támogatja. .jsFájlok esetén a legtisztább csomagszintű jelölő a következő:
{
"type": "module"
}
A végződésű fájlokat .mjsmindig ES modulként kezeli a rendszer, míg a végződésű fájlokat .cjsmindig CommonJS modulként. A jelenlegi Node.js verziók az ESM szintaxist is képesek felismerni néhány kétértelmű fájlban, de a Node.js dokumentációja explicit csomagjelölők használatát javasolja, mivel ezek egyértelműbbek a Node.js, az eszközök és a jövőbeli karbantartás számára.
Ellenőrizd a legközelebbi vezérlő package.json fájlt. A module legfelső szintű típusértéke azt eredményezi, hogy az adott csomagban található .js fájlok ESM szemantikát használnak.
A módosítás előtt olvasd el a hivatalos csomag- és modultípus-szabályokat"type" . Egy csomag CommonJS-ről ESM-re való módosítása egyszerre sok fájlt érinthet. Azt se feledd, hogy a hozzáadás "type": "module"nem telepít hiányzó függőséget, és nem javít ki rossz elérési utat; csak azt határozza meg, hogy a releváns .jsfájlok hogyan értelmeződnek.
A hiányzó csomag valóban telepítve van ebben a projektben?
Ha a hiba egy csupasz csomagot nevez meg, például a lodash, ellenőrizze a függőségi fát ahelyett, hogy feltételezné, hogy egy globálisan telepített csomag vagy egy másik munkaterület teszi elérhetővé.
npm ls lodash
Az npm ls parancs aktuális npm dokumentációja szerint a parancs listázza a telepített csomagverziókat, és jelentheti a hiányzó vagy érvénytelen függőségeket. Ha a csomag közvetlen futásidejű függőség, és nincs telepítve, telepítse a megfelelő projektbe:
npm install lodash
Csupasz csomag importálásához az ESM szintaxisának módosítása előtt ellenőrizd, hogy a csomag szerepel-e az aktuális függőségi fában.
A hivatalos npm telepítési dokumentáció elmagyarázza, hogy egy normál projekttelepítés a függőségeket a helyi node_modulesfába helyezi, és alapértelmezés szerint az explicit módon telepített csomagokat ide menti dependencies.
Egy monorepo esetében futtassa az ellenőrzést abban a munkaterületen, amely az importálandó fájlt birtokolja. A csomag telepítése a tárház más részébe nem jelenti automatikusan azt, hogy az aktuális csomag érvényes deklarált függőséggel rendelkezik.
A csomag neve helyes, de az alútvonal rossz?
Egy csomag létezhet és mégis elutasíthatja a mélyimportálást. A modern csomagok definiálhatnak egy "exports"map-et a . mezőjükben package.json. Amikor ez a mező létezik, a Node.js csak az ott deklarált nyilvános belépési pontokat engedélyezi. A hivatalos Node.js package-entry-point dokumentáció szerint a támogatott Node.js verziókban "exports"elsőbbséget élvez , és a nem listázott alútvonalakat is magában foglalja."main"
Tegyük fel, hogy egy függőség dokumentálja ezt a nyilvános importálást:
import { parse } from 'example-package/parser';
Ne cserélje le egy kitalált belső elérési úttal, például:
import { parse } from 'example-package/dist/internal/parser.js';
A telepített csomag metaadatainak vizsgálata, ha egy csupasz csomag feloldódik, de egy al-elérési út nem. A nyilvános al-elérési utakat a csomag exportálási térképe vezérli, ha van ilyen.
Egy blokkolt "exports"alútvonal gyakran ERR_PACKAGE_PATH_NOT_EXPORTEDa helyett a következőt eredményezi ERR_MODULE_NOT_FOUND. A hibakódban bekövetkező változás hasznos bizonyíték: azt jelenti, hogy a Node.js megtalálta a csomagot, de a kért elérési út nem része a nyilvános interfészének. Használd a csomag dokumentált importálási útvonalát a beágyazás megkerülése helyett.
Lehetséges, hogy az elérési út csak a helyesírásban vagy a kis- és nagybetűkben különbözik?
Ellenőrizd a fájlfában a karaktereket karakterenként. Azok az importálások, amelyek látszólag működnek egy kis- és nagybetűket nem megkülönböztető fejlesztői fájlrendszeren, meghiúsulhatnak egy kis- és nagybetűket megkülönböztető fájlrendszerre történő telepítés után.
Például, ha a valódi fájl:
src/utils/Logger.js
majd a következő importja:
import logger from './utils/logger.js';
nem hordozható, mert Logger.jsa és logger.jsa fájlnevek eltérőek lehetnek.
Hasonlítsa össze az importált fájlt a valódi könyvtárfával. Ellenőrizzen minden mappanevet, fájlnevet, kiterjesztést és a kis- és nagybetűk használatát.
Azt is ellenőrizd, hogy az importálás az importáló modulhoz képest történik-e , nem pedig a shell aktuális könyvtárához képest. Az ESM relatív specifikációi az importáló fájl modul URL-címéhez képest vannak feloldva.
Hogyan láthatod, hogy mit oldana meg a Node.js?
Egy ES modulban import.meta.resolve()segíthet a felbontás vizsgálatában:
A hivatalos Node.js ESM referenciaimport.meta.resolve(specifier) egy modul-relatív feloldási függvényként írja le , amely egy abszolút URL-karakterláncot ad vissza, és tiszteletben tartja a csomagfeloldást és az engedélyezett exportokat.
Van egy fontos kikötés a jelenlegi verzióval kapcsolatban: relatív file:cél esetén import.meta.resolve()akkor is visszaadhatja az URL-t, ha a megfelelő helyi fájl nem létezik. Használd a „Melyik célra oldja fel a csomópont ezt a specifikátort?” kérdés megválaszolásához, majd ellenőrizd, hogy a kapott fájl valóban létezik-e. Hiányzó csomagok vagy érvénytelen csomag-hozzárendelések esetén maga a feloldás is korábban felfedheti a hibát.
Törölnöd kellene a node_modules fájlokat és a lockfile-t?
Nem első válaszként. A hiányzó bővítmény, a helytelen helyi elérési út vagy a nem támogatott csomag-alelérési út nem javítható a függőségek újratelepítésével.
Ha npm lsinkonzisztens fát jelez, a projektnek van egy véglegesített package-lock.json, és reprodukálható, tiszta telepítést szeretne, akkor használja a következőt:
npm ci
A jelenlegi npm ci dokumentáció szerint npm cia(z) ``sheet`` meglévő zárfájlt igényel, node_modulesautomatikusan eltávolítja a meglévő könyvtárat, telepíti a zárolt fát, és nem írja át package.jsona zárfájlt. Ha package.jsona(z) ``sheet`` és a zárfájl között eltérés van, akkor a zár csendes frissítése helyett kilép.
Kerüld a törléssel package-lock.jsoncsak a hiba eltüntetését. Ez egy új függőségi gráf feloldását okozhatja, és egy modulfeloldási hibát függőségi verzióváltozássá alakíthat.
Mi a leggyorsabb hibaelhárítási sorrend?
Mi a hiba neve?
Először ellenőrizze
Tipikus javítás
./local/path
Pontos útvonal és kiterjesztés
Adja hozzá .jsa / jelet .mjs, és javítsa ki a relatív elérési utat
Egy címtár
Akár számítottál rá,index.js
./directory/index.jsExplicit importálás
package-name
npm ls package-name
Telepítse vagy deklarálja helyesen a függőséget
package-name/subpath
Csomag "exports"és hivatalos csomagdokumentációk
Exportált nyilvános alútvonal használata
Egy helyesnek tűnő út
Fájlnév kis- és nagybetűinek használata és a tényleges projektfa
Pontosan illeszkedjen a fájlrendszerhez
Csak egy környezet hibázik
Zárolási fájl, munkaterület, csomópont verzió, fájlrendszer eset
Reprodukálás ugyanazzal a deklarált függőségi fával
Mit kell elkerülni a vakon történő változtatással?
Ne "type": "module"csak azért adj hozzá, mert az importálás sikertelen volt; először ellenőrizd a projekt kívánt modulrendszerét.
Ne távolítsa el a fájlkiterjesztéseket a CommonJS példák utánzása érdekében. A Node.js ESM explicit kiterjesztéseket igényel a relatív és abszolút fájlmeghatározókhoz.
Ne importáljon mélyen privát fájlokat egy függőségből, ha a "exports"térképe támogatott nyilvános belépési pontot biztosít.
Ne feltételezzük, hogy egy sikeres globális npm telepítés elérhetővé tesz egy függőséget egy helyi alkalmazás számára.
Ne töröljön zárolási fájlt rutinszerű gyorsítótár-tisztítási lépésként.
Ne feltételezzük, hogy a munkakönyvtár vezérli a relatív ESM-importálásokat; az importáló modul az alap.
Honnan tudod, hogy a javítás befejeződött?
Futtassa újra ugyanazt a belépési pontot, amely eredetileg hibát jelzett, és ellenőrizze, hogy a modul megoldja-e a problémát anélkül, hogy a hibát egy másik megoldási problémával helyettesítené. Ezután futtassa a projekt szokásos tesztjeit vagy indítási parancsát, hogy megbizonyosodjon arról, hogy a javítás egyetlen import utasításon túl is működik.
A mögöttes megoldási probléma kijavítása után futtassa újra az eredeti parancsot, majd a projekt normál tesztelési vagy indítási munkafolyamatát.
Ha az alkalmazás most egy másik hibát észlel, például a ERR_PACKAGE_PATH_NOT_EXPORTED, ERR_UNKNOWN_FILE_EXTENSIONvagy az export-name hibát, ne kezelje azt ugyanazon problémaként. Ez azt jelenti, hogy a modul feloldása továbbhaladt, és a Node.js most egy konkrétabb kompatibilitási inkompatibilitást jelez.
A lényeg
Node.js ESM esetén ERR_MODULE_NOT_FOUNDa problémát általában a pontos specifikátor visszakövetésével oldják meg, ahelyett, hogy mindent újratelepítenének. A helyi fájloknak explicit kiterjesztésekkel és explicit könyvtárindexekkel kell rendelkezniük. A csupasz csomagokat a megfelelő függőségi fába kell telepíteni. A csomagok alútvonalainak tiszteletben kell tartaniuk a "exports". A vezérlőnek package.jsonmeg kell egyeznie a kívánt modulrendszerrel, és a fájlneveknek pontosan meg kell egyezniük a fájlrendszerrel.
Ha a hibát ebben a sorrendben közelíted meg – specifikátor típusa, valós elérési út, ESM szabályok, függőségi fa, csomagexportálások, majd tiszta telepítés –, akkor általában gyorsan azonosíthatod az okát anélkül, hogy a hibához kapcsolódó változtatásokat kellene végrehajtanod.