Domov
» Základné znalosti
»
Ako opraviť chybu „ERR_MODULE_NOT_FOUND“ v importoch Node.js ESM
Ako opraviť chybu „ERR_MODULE_NOT_FOUND“ v importoch Node.js ESM
ERR_MODULE_NOT_FOUNDznamená, že Node.js dosiahol zavádzač modulov ECMAScript a nedokázal vyriešiť modul požadovaný import, import()alebo vstupným bodom programu. V aktuálnej dokumentácii Node.js je táto chyba konkrétne definovaná ako zlyhanie vyriešenia zavádzača ESM; analogická chyba CommonJS je MODULE_NOT_FOUND. Pozrite si oficiálnu referenciu chýb Node.js.
Najrýchlejšou opravou je identifikovať, aký typ špecifikátora zlyhal, predtým ako čokoľvek zmeníte. Relatívny import, napríklad , ./utils/logger.jssa riadi inými pravidlami ako import balíka, napríklad lodash. Node.js ESM sa tiež rieši inak ako CommonJS: relatívny import vyžaduje explicitné prípony súborov a indexy adresárov sa nehádajú automaticky. Tieto rozdiely vysvetľujú mnohé zlyhania po prechode z . require()na import.
Čo presne Node.js nedokáže nájsť?
Začnite s prvým riadkom chyby, nie s celým sledovaním zásobníka. Zvyčajne vám to prezradí neriešený cieľ aj súbor, ktorý sa ho pokúsil importovať. Zaraďte zlyhávajúci špecifikátor do jednej z týchto skupín:
Relatívny súbor:./utils/logger.js alebo ../config.js.
Absolútny súbor alebo URL adresa súboru: absolútna cesta alebo file:URL adresa.
Holý balík:lodash , express, alebo @scope/pkg.
Podcesta balíka:some-package/feature.js .
Alias importu balíka: interný špecifikátor začínajúci na #, definovaný prostredníctvom package.json"imports".
Najprv si prečítajte prvý riadok s chybou: tento príklad identifikuje holý názov balíka, takže ďalšie kontroly by sa mali zamerať na inštaláciu závislostí a rozlíšenie balíkov.
Oficiálna dokumentácia k modulom Node.js ECMAScript oddeľuje relatívne, holé a absolútne špecifikátory, pretože sa neriešia rovnakým spôsobom. Keď zistíte, ktorá kategória zlyhala, vyhnite sa náhodným opravám, ako je vymazanie node_modulesalebo zmena, package.jsonkým na to dôkazy neukazujú.
Obsahuje lokálny import ESM skutočnú príponu súboru?
Pre relatívne a absolútne špecifikátory ESM vyžaduje Node.js príponu súboru. Nevyhľadáva .js, .mjsalebo .jsonpo neúspešnom relatívnom importe. Aktuálna dokumentácia Node.js nazýva toto pravidlo povinnými príponami súborov a tiež uvádza, že indexy adresárov musia byť úplne zadané.
Ak je súbor na disku src/utils/logger.js, toto je bezpečný formulár ESM:
import { logger } from './utils/logger.js';
Nie:
import { logger } from './utils/logger';
Node.js ESM nevykonáva vyhľadávanie prípon pre relatívne importy. Skutočnú príponu súboru napíšte do špecifikátora modulu.
Toto je jeden z najdôležitejších rozdielov oproti rozlíšeniu CommonJS. Oficiálna dokumentácia balíkov Node.js vysvetľuje, že require()je možné vyskúšať rozšírenia a priečinky, zatiaľ čo zavádzač ESM nevykonáva vyhľadávanie rozšírení.
Importujete adresár namiesto skutočného súboru?
Projekt CommonJS sa mohol spoliehať na import adresára, ktorý nakoniec načítal súbor index.js. Nepredpokladajte, že zavádzač ESM urobí to isté. Ak je vaša štruktúra:
src/
config/
index.js
app.js
uprednostňujem:
import config from './config/index.js';
skôr než:
import config from './config';
Lokálne zlyhanie pri riešení zvyčajne ukazuje na presnú neriešenú cestu. Skontrolujte cestu, príponu a či import smeruje do adresára a nie do súboru.
Oficiálna dokumentácia ESM uvádza, že indexy adresárov, ako napríklad , ./startup/index.jsmusia byť úplne špecifikované. Ak pridanie rozšírenia stále zlyhá, porovnajte každý segment cesty so skutočným stromom adresárov.
Naozaj projekt funguje ako ESM?
Node.js podporuje moduly CommonJS aj ECMAScript. Pre .jssúbory je najjasnejším ukazovateľom na úrovni balíka:
{
"type": "module"
}
Súbory končiace na sa .mjsvždy považujú za moduly ES, zatiaľ čo súbory končiace na sa .cjsvždy považujú za moduly CommonJS. Aktuálne verzie Node.js dokážu tiež rozpoznať syntax ESM v niektorých nejednoznačných súboroch, ale dokumentácia Node.js odporúča explicitné značky balíkov, pretože sú jasnejšie pre Node.js, nástroje a budúcu údržbu.
Skontrolujte najbližší riadiaci súbor package.json. Hodnota typu najvyššej úrovne module spôsobí, že súbory .js v danom balíku budú používať sémantiku ESM.
Pred zmenou si prečítajte oficiálne pravidlá pre balíky a typy modulov"type" . Zmena balíka z CommonJS na ESM môže ovplyvniť viacero súborov naraz. Pamätajte tiež, že pridanie "type": "module"neinštaluje chýbajúcu závislosť ani neopravuje nesprávnu cestu; určuje iba to, ako .jssa interpretujú relevantné súbory.
Je chýbajúci balík v tomto projekte skutočne nainštalovaný?
Ak chyba pomenuje holý balík, napríklad lodash, skontrolujte strom závislostí namiesto predpokladu, že ho sprístupňuje globálne nainštalovaný balík alebo iný pracovný priestor.
npm ls lodash
Aktuálna dokumentácia npm pre npm ls uvádza, že príkaz vypíše nainštalované verzie balíkov a môže hlásiť chýbajúce alebo neplatné závislosti. Ak je balík priamou závislosťou za behu a nie je nainštalovaný, nainštalujte ho do správneho projektu:
npm install lodash
V prípade importu holého balíka overte, či sa balík nachádza v aktuálnom strome závislostí, pred zmenou syntaxe ESM.
Oficiálna dokumentácia k inštalácii npm vysvetľuje, že bežná inštalácia projektu umiestňuje závislosti do lokálneho node_modulesstromu a štandardne ukladá explicitne nainštalované balíky do dependencies.
V monorepozitári spustite kontrolu v pracovnom priestore, ktorý vlastní importovaný súbor. Inštalácia balíka inde v repozitári automaticky neznamená, že aktuálny balík má platnú deklarovanú závislosť.
Je názov balíka správny, ale podcesta nesprávna?
Balík môže existovať a stále odmietnuť hlboký import. Moderné balíky môžu definovať "exports"mapu vo svojom poli package.json. Keď toto pole existuje, Node.js povoľuje iba verejné vstupné body deklarované v ňom. Oficiálna dokumentácia k vstupným bodom balíka Node.js uvádza, že "exports"má prednosť pred "main"v podporovaných verziách Node.js a zapuzdruje neuvedené podcesty.
Predpokladajme, že závislosť dokumentuje tento verejný import:
import { parse } from 'example-package/parser';
Nenahrádzajte ho uhádnou vnútornou cestou, ako napríklad:
import { parse } from 'example-package/dist/internal/parser.js';
Skontrolujte metadáta nainštalovaného balíka, keď sa holý balík rozlúšti, ale podcesta nie. Verejné podcesty sú riadené mapou exportov balíka, ak je k dispozícii.
Zablokovaná "exports"podcesta často vytvára ERR_PACKAGE_PATH_NOT_EXPORTEDnamiesto ERR_MODULE_NOT_FOUND. Táto zmena v chybovom kóde je užitočným dôkazom: znamená to, že Node.js našiel balík, ale požadovaná cesta nie je súčasťou jeho verejného rozhrania. Namiesto obchádzania zapuzdrenia použite zdokumentovanú cestu importu balíka.
Mohla by sa cesta líšiť iba pravopisom alebo veľkosťou písmen?
Skontrolujte skutočný znak v strome súborov. Importy, ktoré zdanlivo fungujú na vývojovom súborovom systéme bez rozlišovania malých a veľkých písmen, môžu po nasadení do súborového systému rozlišujúceho malé a veľké písmená zlyhať.
Napríklad, ak je skutočný súbor:
src/utils/Logger.js
potom import:
import logger from './utils/logger.js';
nie je prenosný, pretože Logger.jsa logger.jsmôžu mať rôzne názvy súborov.
Porovnajte import so skutočným adresárovým stromom. Overte každý názov priečinka, názov súboru, príponu a veľkosť písmena.
Taktiež overte, či je import relatívny vzhľadom na importujúci modul , nie vzhľadom na aktuálny adresár shellu. Relatívne špecifikátory ESM sa rozpoznávajú vzhľadom na URL adresu modulu importujúceho súboru.
Ako môžete vidieť, čo by Node.js vyriešil?
V module ES import.meta.resolve()môže pomôcť skontrolovať rozlíšenie:
Oficiálna referencia Node.js ESM opisuje import.meta.resolve(specifier)funkciu relatívneho rozlišovania modulov, ktorá vracia absolútny reťazec URL a rešpektuje rozlíšenie balíkov a povolené exporty.
Existuje dôležité upozornenie týkajúce sa aktuálnej verzie: pre relatívny file:cieľ import.meta.resolve()môže vrátiť URL adresu, aj keď zodpovedajúci lokálny súbor neexistuje. Použite ho na zodpovedanie otázky „Na aký cieľ uzol prekladá tento špecifikátor?“ a potom overte, či výsledný súbor skutočne existuje. V prípade chýbajúcich holých balíkov alebo neplatných mapovaní balíkov môže samotné prekladanie odhaliť chybu skôr.
Mali by ste odstrániť node_modules a lockfile?
Nie ako prvá odpoveď. Chýbajúce rozšírenie, nesprávna lokálna cesta alebo nepodporovaná podcesta balíka sa neopravia preinštalovaním závislostí.
Ak npm lshlási nekonzistentný strom, projekt má potvrdenú inštaláciu package-lock.jsona chcete reprodukovateľnú čistú inštaláciu, použite:
npm ci
Aktuálna dokumentácia npm ci uvádza, že npm civyžaduje existujúci lockfile, node_modulesautomaticky odstráni existujúci adresár, nainštaluje uzamknutý strom a neprepisuje package.jsonlockfile. Ak package.jsonsa a lockfile nezhodujú, ukončí sa namiesto tichej aktualizácie zámku.
Vyhnite sa mazaniu package-lock.jsonlen preto, aby chyba zmizla. To môže spôsobiť vyriešenie nového grafu závislostí a zmeniť chybu pri riešení modulov na zmenu verzie závislosti.
Aké je najrýchlejšie poradie riešenia problémov?
Aké sú názvy chýb
Najprv skontrolujte
Typická oprava
./local/path
Presná cesta a rozšírenie
Pridajte .js/ .mjsa opravte relatívnu cestu
Adresár
Či ste očakávaliindex.js
./directory/index.jsExplicitný import
package-name
npm ls package-name
Nainštalujte alebo správne deklarujte závislosť
package-name/subpath
Balík "exports"a oficiálna dokumentácia k balíku
Použite exportovanú verejnú podcestu
Cesta, ktorá vyzerá správne
Veľké a malé písmená názvu súboru a skutočný strom projektu
Presne zhodujte súborový systém
Zlyhá iba jedno prostredie
Lockfile, pracovný priestor, verzia uzla, prípad súborového systému
Reprodukovať s rovnakým deklarovaným stromom závislostí
Čomu by ste sa mali vyhnúť pri slepých zmenách?
Nepridávajte "type": "module"len preto, že import zlyhal; najskôr potvrďte zamýšľaný systém modulov projektu.
Neodstraňujte prípony súborov, aby ste napodobnili príklady CommonJS. Node.js ESM vyžaduje explicitné prípony pre relatívne a absolútne špecifikátory súborov.
Neimportujte hlboko súkromné súbory zo závislosti, ak jej "exports"mapa poskytuje podporovaný verejný vstupný bod.
Nepredpokladajte, že úspešná globálna inštalácia npm sprístupní závislosť lokálnej aplikácii.
Neodstraňujte uzamykateľný súbor ako rutinný krok čistenia vyrovnávacej pamäte.
Nepredpokladajte, že pracovný adresár riadi relatívne importy ESM; základom je importujúci modul.
Ako viete, že oprava je dokončená?
Znovu spustite ten istý vstupný bod, ktorý pôvodne zlyhal, a overte, či sa modul vyriešil bez nahradenia chyby iným problémom s riešením. Potom spustite bežné testy projektu alebo príkaz spustenia, aby ste vedeli, že oprava funguje aj po jednom príkaze importu.
Po oprave základného problému s riešením znova spustite pôvodný príkaz a potom bežný testovací alebo spúšťací pracovný postup projektu.
Ak aplikácia teraz narazí na inú chybu, ako napríklad ERR_PACKAGE_PATH_NOT_EXPORTED, ERR_UNKNOWN_FILE_EXTENSIONalebo chybu s názvom exportu, nepovažujte to za rovnaký problém. Znamená to, že riešenie modulov pokročilo ďalej a Node.js teraz hlási špecifickejšiu nekompatibilitu.
Zrátané a podčiarknuté
V prípade Node.js ESM ERR_MODULE_NOT_FOUNDsa problém zvyčajne rieši sledovaním presného špecifikátora, a nie preinštalovaním všetkého. Lokálne súbory potrebujú explicitné prípony a explicitné indexy adresárov. Holé balíky musia byť nainštalované v správnom strome závislostí. Podcesty balíkov musia rešpektovať "exports". Riadiaci prvok package.jsonsa musí zhodovať so zamýšľaným systémom modulov a názvy súborov sa musia presne zhodovať so súborovým systémom.
Keď k chybe pristupujete v tomto poradí – typ špecifikátora, skutočná cesta, pravidlá ESM, strom závislostí, exporty balíkov a potom čistá inštalácia – zvyčajne dokážete príčinu rýchlo identifikovať bez zavedenia nesúvisiacich zmien.