Početna
» Osnovno znanje
»
Kako ispraviti "ERR_MODULE_NOT_FOUND" u Node.js ESM uvozima
Kako ispraviti "ERR_MODULE_NOT_FOUND" u Node.js ESM uvozima
ERR_MODULE_NOT_FOUNDznači da je Node.js došao do ECMAScript modula za učitavanje i nije mogao razriješiti modul koji je zatražio import, import()ili ulazna točka programa. U trenutnoj Node.js dokumentaciji, ova greška je posebno definirana kao neuspjeh razrješenja ESM učitavača; analogna CommonJS greška je MODULE_NOT_FOUND. Pogledajte službenu Node.js referencu za greške .
Najbrže rješenje je identificirati vrstu specifikatora koji je doživio neuspjeh prije nego što se išta promijeni. Relativni uvoz kao što ./utils/logger.jsje slijedi drugačija pravila od uvoza paketa kao što je lodash. Node.js ESM se također rješava drugačije od CommonJS-a: relativni uvozi zahtijevaju eksplicitne ekstenzije datoteka, a indeksi direktorija se ne pogađaju automatski. Te razlike objašnjavaju mnoge neuspjehe nakon prelaska s . require()na import.
Što točno Node.js ne uspijeva pronaći?
Započnite s prvim retkom pogreške, a ne s cijelim tragom stoga. Obično vam govori i neriješeni cilj i datoteku koja ga je pokušala uvesti. Klasificirajte neuspjeli specifikator u jednu od ovih skupina:
Relativna datoteka:./utils/logger.js ili ../config.js.
Apsolutna datoteka ili URL datoteke: apsolutni put ili file:URL.
Goli paket:lodash , express, ili @scope/pkg.
Podputanja paketa:some-package/feature.js .
Alias uvoza paketa: interni specifikator koji počinje s #, definiran kroz package.json"imports".
Prvo pročitajte prvi redak pogreške: ovaj primjer identificira naziv paketa, pa bi se sljedeće provjere trebale usredotočiti na instalaciju ovisnosti i rješavanje paketa.
Službena dokumentacija Node.js ECMAScript modula odvaja relativne, gole i apsolutne specifikatore jer se ne rješavaju na isti način. Nakon što saznate koja je kategorija propala, izbjegavajte nasumične ispravke poput brisanja node_modulesili mijenjanja package.jsondok dokazi ne upućuju na to.
Uključuje li lokalni ESM uvoz stvarnu ekstenziju datoteke?
Za relativne i apsolutne ESM specifikatore, Node.js zahtijeva ekstenziju datoteke. Ne traži .js, .mjsili .jsonnakon neuspjelog relativnog uvoza. Trenutna Node.js dokumentacija ovo pravilo naziva obveznim ekstenzijama datoteka i također navodi da indeksi direktorija moraju biti u potpunosti navedeni.
Ako je datoteka na disku src/utils/logger.js, ovo je siguran ESM obrazac:
import { logger } from './utils/logger.js';
Ne:
import { logger } from './utils/logger';
Node.js ESM ne vrši pretraživanje ekstenzija za relativne uvoze. Upišite stvarnu ekstenziju datoteke u specifikator modula.
Ovo je jedna od najvažnijih razlika u odnosu na CommonJS rezoluciju. Službena dokumentacija Node.js paketa objašnjava da require()se mogu isprobati ekstenzije i mape, dok ESM loader ne vrši pretraživanje ekstenzija.
Uvozite li direktorij umjesto stvarne datoteke?
CommonJS projekt se možda oslanjao na uvoz direktorija koji je na kraju učitavao datoteku index.js. Nemojte pretpostavljati da će ESM loader učiniti isto. Ako je vaša struktura:
src/
config/
index.js
app.js
preferiram:
import config from './config/index.js';
a ne:
import config from './config';
Lokalna greška u razrješavanju obično ukazuje na točan nerazriješeni put. Provjerite put, ekstenziju i cilja li uvoz direktorij, a ne datoteku.
Službena ESM dokumentacija navodi da indeksi direktorija kao što su ./startup/index.jsmoraju biti u potpunosti navedeni. Ako dodavanje ekstenzije i dalje ne uspije, usporedite svaki segment puta sa stvarnim stablom direktorija.
Da li se projekt stvarno izvodi kao ESM?
Node.js podržava i CommonJS i ECMAScript module. Za .jsdatoteke, najjasnija oznaka na razini paketa je:
{
"type": "module"
}
Datoteke koje završavaju na .mjsuvijek se tretiraju kao ES moduli, dok se datoteke koje završavaju .cjsna uvijek tretiraju kao CommonJS. Trenutne verzije Node.js-a također mogu otkriti ESM sintaksu u nekim dvosmislenim datotekama, ali Node.js dokumentacija preporučuje eksplicitne oznake paketa jer su jasnije za Node.js, alate i buduće održavanje.
Provjerite najbliži kontrolni package.json. Vrijednost tipa najviše razine module omogućuje .js datotekama u tom paketu korištenje ESM semantike.
Pročitajte službena pravila za pakete i tipove modula prije promjene "type". Promjena paketa iz CommonJS-a u ESM može utjecati na više datoteka odjednom. Također imajte na umu da dodavanje "type": "module"ne instalira nedostajuću ovisnost niti ispravlja pogrešan put; ono samo određuje kako se relevantne .jsdatoteke interpretiraju.
Je li nedostajući paket zapravo instaliran u ovom projektu?
Ako greška imenuje goli paket kao što je lodash, provjerite stablo ovisnosti umjesto da pretpostavite da ga globalno instalirani paket ili neki drugi radni prostor čini dostupnim.
npm ls lodash
Trenutna npm dokumentacija za npm ls kaže da naredba navodi instalirane verzije paketa i može prijaviti nedostajuće ili nevažeće ovisnosti. Ako je paket izravna ovisnost u vremenu izvođenja i nije instaliran, instalirajte ga u ispravan projekt:
npm install lodash
Za uvoz golog paketa, provjerite je li paket u trenutnom stablu ovisnosti prije promjene ESM sintakse.
Službena dokumentacija za instalaciju npm-a objašnjava da normalna instalacija projekta smješta ovisnosti u lokalno node_modulesstablo i, prema zadanim postavkama, sprema eksplicitno instalirane pakete u dependencies.
U monorepozitoriju, pokrenite provjeru u radnom prostoru koji je vlasnik datoteke za uvoz. Instaliranje paketa negdje drugdje u repozitoriju ne znači automatski da trenutni paket ima valjanu deklariranu ovisnost.
Je li naziv paketa ispravan, ali je podputanja pogrešna?
Paket može postojati i dalje odbijati duboki uvoz. Moderni paketi mogu definirati mapu "exports"u svojim package.json. Kada to polje postoji, Node.js dopušta samo javne ulazne točke deklarirane tamo. Službena dokumentacija o ulaznim točkama paketa Node.js kaže "exports"da ima prednost nad "main"u podržanim verzijama Node.js-a i enkapsulira nenavedene podputove.
Pretpostavimo da ovisnost dokumentira ovaj javni uvoz:
import { parse } from 'example-package/parser';
Nemojte ga zamijeniti nagađanjem unutarnjeg puta kao što je:
import { parse } from 'example-package/dist/internal/parser.js';
Pregledajte metapodatke instaliranog paketa kada se goli paket razriješi, ali podputanja ne. Javne podputanje kontrolira mapa izvoza paketa ako je prisutna.
Blokirana "exports"podputnja često stvara ERR_PACKAGE_PATH_NOT_EXPORTED, a ne ERR_MODULE_NOT_FOUND. Ta promjena u kodu pogreške koristan je dokaz: to znači da je Node.js pronašao paket, ali tražena putanja nije dio njegovog javnog sučelja. Koristite dokumentiranu putanju uvoza paketa umjesto zaobilaženja enkapsulacije.
Može li se put razlikovati samo po pravopisu ili velikim i malim slovima?
Provjerite stvarno stablo datoteka za znakove. Uvozi koji izgledaju kao da rade na razvojnom datotečnom sustavu koji ne razlikuje velika i mala slova mogu propasti nakon implementacije u datotečni sustav koji razlikuje velika i mala slova.
Na primjer, ako je stvarna datoteka:
src/utils/Logger.js
zatim uvoz:
import logger from './utils/logger.js';
nije prenosiv, jer Logger.jsi logger.jsmogu biti različita imena datoteka.
Usporedite uvoz sa stvarnim stablom direktorija. Provjerite svaki naziv mape, naziv datoteke, ekstenziju i velika i mala slova.
Također provjerite je li uvoz relativan u odnosu na modul koji se uvozi , a ne na trenutni direktorij ljuske. ESM relativni specifikatori se rješavaju relativno u odnosu na URL modula datoteke koja se uvozi.
Kako možete vidjeti što bi Node.js riješio?
U ES modulu import.meta.resolve()može pomoći u provjeri rezolucije:
Službena Node.js ESM referenca opisuje import.meta.resolve(specifier)funkciju razlučivanja relativne modula koja vraća apsolutni URL niz i poštuje razlučivost paketa i dopuštene izvoze.
Postoji važno upozorenje za trenutnu verziju: za relativni file:cilj, import.meta.resolve()može vratiti URL čak i kada odgovarajuća lokalna datoteka ne postoji. Koristite ga za odgovor na pitanje "Na koji cilj čvor razrješava ovaj specifikator?", a zatim provjerite postoji li rezultirajuća datoteka. Za nedostajuće gole pakete ili nevažeće mapiranje paketa, samo razrješenje i dalje može ranije otkriti kvar.
Trebate li izbrisati node_modules i lockfile?
Ne kao prvi odgovor. Nedostaje proširenje, kriva lokalna putanja ili nepodržana podputnja paketa neće se popraviti ponovnom instalacijom ovisnosti.
Ako npm lsse prijavi nekonzistentno stablo, projekt ima potvrđenu promjenu package-lock.jsoni želite ponovljivu čistu instalaciju, upotrijebite:
npm ci
Trenutna npm ci dokumentacija navodi da npm cizahtijeva postojeću lockfile datoteku, automatski uklanja postojeći node_modulesdirektorij, instalira zaključano stablo i ne prepisuje package.jsonlockfile. Ako package.jsonse i lockfile ne slažu, izlazi umjesto da tiho ažurira zaključavanje.
Izbjegavajte brisanje package-lock.jsonsamo kako biste uklonili grešku. To može uzrokovati rješavanje novog grafa ovisnosti i pretvoriti grešku u rješavanju modula u promjenu verzije ovisnosti.
Koji je najbrži redoslijed rješavanja problema?
Kako se nazivaju greške
Prvo provjerite
Tipično rješenje
./local/path
Točan put i proširenje
Dodajte .js/ .mjsi ispravite relativnu putanju
Imenik
Jeste li očekivaliindex.js
Uvozi ./directory/index.jseksplicitno
package-name
npm ls package-name
Instalirajte ili ispravno deklarirajte ovisnost
package-name/subpath
Paket "exports"i službena dokumentacija paketa
Koristite izvezenu javnu podputnju
Put koji izgleda ispravno
Velika i mala veličina imena datoteke i stvarno stablo projekta
Točno podudaraj datotečni sustav
Samo jedno okruženje ne uspijeva
Zaključana datoteka, radni prostor, verzija čvora, slučaj datotečnog sustava
Reproduciraj s istim deklariranim stablom ovisnosti
Što biste trebali izbjegavati nagle promjene?
Nemojte dodavati "type": "module"samo zato što uvoz nije uspio; prvo potvrdite namjeravani sustav modula projekta.
Nemojte uklanjati ekstenzije datoteka kako biste oponašali primjere CommonJS-a. Node.js ESM zahtijeva eksplicitne ekstenzije za relativne i apsolutne specifikatore datoteka.
Nemojte duboko uvoziti privatne datoteke iz ovisnosti kada njena "exports"mapa pruža podržanu javnu ulaznu točku.
Nemojte pretpostavljati da uspješna globalna npm instalacija čini ovisnost dostupnom lokalnoj aplikaciji.
Nemojte brisati lockfile kao rutinski korak čišćenja predmemorije.
Nemojte pretpostavljati da radni direktorij kontrolira relativne ESM uvoze; modul za uvoz je osnova.
Kako znate da je popravak gotov?
Ponovno pokrenite istu ulaznu točku koja je izvorno propala i potvrdite da se modul rješava bez zamjene pogreške drugim problemom rješavanja. Zatim pokrenite uobičajene testove projekta ili naredbu za pokretanje kako biste znali da rješenje funkcionira i nakon jedne naredbe za uvoz.
Nakon ispravljanja temeljnog problema s rješavanjem problema, ponovno pokrenite izvornu naredbu, a zatim normalni tijek rada pri testiranju ili pokretanju projekta.
Ako aplikacija sada dođe do druge pogreške kao što je ERR_PACKAGE_PATH_NOT_EXPORTED, ERR_UNKNOWN_FILE_EXTENSION, ili pogreška izvoznog naziva, nemojte to tretirati kao isti problem. To znači da je rješavanje modula dalje napredovalo i Node.js sada prijavljuje specifičniju nekompatibilnost.
Zaključak
Za Node.js ESM, ERR_MODULE_NOT_FOUNDproblem se obično rješava praćenjem točnog specifikatora umjesto ponovne instalacije svega. Lokalne datoteke trebaju eksplicitne ekstenzije i eksplicitne indekse direktorija. Goli paketi moraju biti instalirani u ispravno stablo ovisnosti. Podpute paketa moraju poštivati "exports". Upravljanje package.jsonmora odgovarati namjeravanom sustavu modula, a nazivi datoteka moraju točno odgovarati datotečnom sustavu.
Nakon što pristupite pogrešci tim redoslijedom - tip specifikatora, stvarna putanja, ESM pravila, stablo ovisnosti, izvoz paketa, a zatim čista instalacija - obično možete brzo identificirati uzrok bez uvođenja nepovezanih promjena.