Etusivu
» Perustieto
»
Kuinka korjata "ERR_MODULE_NOT_FOUND" Node.js ESM -tuonneissa
Kuinka korjata "ERR_MODULE_NOT_FOUND" Node.js ESM -tuonneissa
ERR_MODULE_NOT_FOUNDimporttarkoittaa, että Node.js saavutti ECMAScript-moduulin latausohjelman eikä pystynyt ratkaisemaan , tai ohjelman aloituskohdan pyytämää moduulia import(). Nykyisessä Node.js-dokumentaatiossa tämä virhe on määritelty erityisesti ESM-lataajan ratkaisuvirheeksi; vastaava CommonJS-virhe on MODULE_NOT_FOUND. Katso virallinen Node.js-virheviite .
Nopein korjaus on tunnistaa epäonnistuneen määrittelyn tyyppi ennen kuin mitään muutetaan. Suhteellinen tuonti, kuten , ./utils/logger.jsnoudattaa eri sääntöjä kuin pakettituonti, kuten lodash. Node.js ESM ratkaisee myös ongelman eri tavalla kuin CommonJS: suhteelliset tuonnit vaativat eksplisiittiset tiedostopäätteet, eikä hakemistoindeksejä arvata automaattisesti. Nämä erot selittävät monia virheitä require()siirryttäessä import.
Mitä Node.js tarkalleen ottaen ei löydä?
Aloita virheen ensimmäisestä rivistä, älä koko pinon jäljityksestä. Se yleensä kertoo sekä ratkaisemattoman kohteen että tiedoston, josta sitä yritettiin tuoda. Luokittele virheellinen määrite johonkin näistä ryhmistä:
Suhteellinen tiedosto:./utils/logger.js tai ../config.js.
Absoluuttinen tiedosto tai tiedoston URL-osoite: absoluuttinen polku tai file:URL-osoite.
Paljas paketti:lodash , express, tai @scope/pkg.
Paketin alipolku:some-package/feature.js .
Paketin tuontialias: sisäinen määrittelijä, joka alkaa merkeillä #, määriteltynä kautta package.json"imports".
Lue ensin ensimmäinen virherivi: tämä esimerkki tunnistaa pelkän paketin nimen, joten seuraavien tarkistusten tulisi keskittyä riippuvuuksien asennukseen ja paketin ratkaisuun.
Virallisissa Node.js ECMAScript -moduulien dokumentaatioissa erotellaan suhteelliset, paljaat ja absoluuttiset määrittelijät, koska ne eivät ratkaise ongelmia samalla tavalla. Kun tiedät, mikä kategoria epäonnistui, vältä satunnaisia korjauksia, kuten poistamista node_modulestai muuttamista, package.jsonkunnes todisteet viittaavat siihen.
Sisältääkö paikallinen ESM-tuonti tiedoston todellisen päätteen?
Suhteellisten ja absoluuttisten ESM-määrittelijöiden kohdalla Node.js vaatii tiedostopäätteen. Se ei etsi .js, .mjstai .jsonepäonnistuneen suhteellisen tuonnin jälkeen. Nykyisessä Node.js-dokumentaatiossa tätä sääntöä kutsutaan pakolliseksi tiedostopäätteeksi ja todetaan myös, että hakemistoindeksit on määritettävä kokonaan.
Jos levyllä oleva tiedosto on src/utils/logger.js, tämä on turvallinen ESM-muoto:
import { logger } from './utils/logger.js';
Ei:
import { logger } from './utils/logger';
Node.js ESM ei suorita tiedostopäätehakua suhteellisille tuonneille. Kirjoita todellinen tiedostopääte moduulimääritteeseen.
Tämä on yksi tärkeimmistä eroista CommonJS-ratkaisuun verrattuna. Node.js-paketin virallinen dokumentaatio selittää, että se require()voi kokeilla laajennuksia ja kansioita, kun taas ESM-lataaja ei suorita laajennushakua.
Tuotko hakemistoa varsinaisen tiedoston sijaan?
CommonJS-projekti on saattanut luottaa hakemiston tuontiin, joka lopulta latasi index.js. Älä oleta ESM-lataajan tekevän samoin. Jos rakenteesi on:
src/
config/
index.js
app.js
mieluummin:
import config from './config/index.js';
sen sijaan, että:
import config from './config';
Paikallinen ratkaisuvirhe viittaa yleensä täsmälleen ratkaisemattomaan polkuun. Tarkista polku, tiedostotunniste ja se, kohdistuuko tuonti hakemistoon tiedoston sijaan.
ESM:n virallisessa dokumentaatiossa todetaan, että hakemistoindeksit, kuten , ./startup/index.json määriteltävä kokonaan. Jos tiedostotunnisteen lisääminen epäonnistuu edelleen, vertaa jokaista polkusegmenttiä varsinaiseen hakemistopuuhun.
Toimiiko projekti todella ESM:nä?
Node.js tukee sekä CommonJS- että ECMAScript-moduuleja. .jsTiedostojen osalta selkein pakettitason merkintä on:
{
"type": "module"
}
Tiedostoja, jotka päättyvät merkkijonoon, .mjskäsitellään aina ES-moduuleina, kun taas tiedostoja, jotka päättyvät merkkijonoon, .cjskäsitellään aina CommonJS-tiedostoina. Nykyiset Node.js-versiot pystyvät myös havaitsemaan ESM-syntaksin joissakin epäselvissä tiedostoissa, mutta Node.js-dokumentaatio suosittelee eksplisiittisiä pakettimerkkejä, koska ne ovat selkeämpiä Node.js:n, työkalujen ja tulevan ylläpidon kannalta.
Tarkista lähimpänä oleva ohjaava package.json-tiedosto. Ylimmän tason tyyppiarvo module saa kyseisen paketin .js-tiedostot käyttämään ESM-semantiikkaa.
Lue viralliset paketti- ja moduulityyppisäännöt ennen muuttamista "type". Paketin vaihtaminen CommonJS:stä ESM:ään voi vaikuttaa useisiin tiedostoihin kerralla. Muista myös, että lisääminen "type": "module"ei asenna puuttuvaa riippuvuutta tai korjaa väärää polkua; se vain määrittää, miten asiaankuuluvat .jstiedostot tulkitaan.
Onko puuttuva paketti todella asennettu tähän projektiin?
Jos virhe nimeää paljaan paketin, kuten lodash, tarkista riippuvuuspuu sen sijaan, että olettaisit globaalisti asennetun paketin tai toisen työtilan asettavan sen saataville.
npm ls lodash
Nykyisessä npm-dokumentaatiossa npm ls -komennolle sanotaan, että komento listaa asennetut pakettiversiot ja voi raportoida puuttuvat tai virheelliset riippuvuudet. Jos paketti on suora suorituksenaikainen riippuvuus eikä sitä ole asennettu, asenna se oikeaan projektiin:
npm install lodash
Jos tuot pelkän paketin, varmista, että paketti on nykyisessä riippuvuuspuussa ennen ESM-syntaksin muuttamista.
Virallisessa npm:n asennusdokumentaatiossa selitetään, että normaalissa projektin asennuksessa riippuvuudet sijoitetaan paikalliseen node_modulespuuhun ja oletuksena tallennetaan eksplisiittisesti asennetut paketit kansioon dependencies.
Suorita tarkistus monorepossa tuotavan tiedoston omistavassa työtilassa. Paketin asentaminen muualle repositorioon ei automaattisesti tarkoita, että nykyisellä paketilla on kelvollinen ilmoitettu riippuvuus.
Onko paketin nimi oikein, mutta alipolku väärin?
Paketti voi olla olemassa ja silti hylätä syvätuonnin. Nykyaikaiset paketit voivat määritellä mapin "exports". package.jsonKun kyseinen kenttä on olemassa, Node.js sallii vain siellä ilmoitetut julkiset aloituspisteet. Virallisessa Node.js:n package-entry-point-dokumentaatiossa sanotaan, että "exports"on etusijalla "main"tuetuissa Node.js-versioissa ja kapseloi listaamattomat alipolut.
Oletetaan, että riippuvuus dokumentoi tämän julkisen tuonnin:
import { parse } from 'example-package/parser';
Älä korvaa sitä arvatulla sisäisellä polulla, kuten:
import { parse } from 'example-package/dist/internal/parser.js';
Tarkasta asennetun paketin metatiedot, kun paljas paketti löytyy, mutta alipolku ei. Julkisia alipolkuja ohjaa paketin vientikartta, jos sellainen on.
Estetty "exports"alipolku tuottaa usein ERR_PACKAGE_PATH_NOT_EXPORTEDeikä ERR_MODULE_NOT_FOUND. Tämä virhekoodin muutos on hyödyllinen todiste: se tarkoittaa, että Node.js löysi paketin, mutta pyydetty polku ei ole osa sen julkista rajapintaa. Käytä paketin dokumentoitua tuontipolkua kapseloinnin ohittamisen sijaan.
Voisiko polku erota vain oikeinkirjoituksen tai kirjainkoon suhteen?
Tarkista varsinainen tiedostopuu merkki merkkien varalta. Tuonnit, jotka näyttävät toimivan kirjainkokoa erottelemattomassa kehitystiedostojärjestelmässä, saattavat epäonnistua kirjainkokoa erottelevaan tiedostojärjestelmään käyttöönoton jälkeen.
Esimerkiksi, jos oikea tiedosto on:
src/utils/Logger.js
sitten tuonti:
import logger from './utils/logger.js';
ei ole siirrettävä, koska Logger.jsja logger.jsvoivat olla eri tiedostonimiä.
Vertaa tuontia todelliseen hakemistopuuhun. Tarkista jokaisen kansion nimi, tiedostonimi, tiedostopääte ja kirjainkoko.
Varmista myös, että tuonti tapahtuu suhteessa tuovaan moduuliin , ei komentotulkin nykyiseen hakemistoon. ESM:n suhteelliset määritteet ratkaistaan tuotavan tiedoston moduulin URL-osoitteen suhteen.
Mistä näet, mitä Node.js ratkaisisi?
ES-moduulissa import.meta.resolve()voi auttaa tarkistamaan resoluution:
Virallinen Node.js ESM -viite kuvaa import.meta.resolve(specifier)sitä moduulikohtaisesti suhteellisena resoluutiofunktiona, joka palauttaa absoluuttisen URL-merkkijonon ja ottaa huomioon pakettien resoluution ja sallitut viennit.
Nykyisessä versiossa on tärkeä varauma: suhteellisen file:kohteen URL-osoite voidaan palauttaa, import.meta.resolve()vaikka vastaavaa paikallista tiedostoa ei olisi olemassa. Käytä sitä vastaamaan kysymykseen "Mihin kohteeseen solmu tulkitsee tämän määritteen?" ja varmista sitten, että tuloksena oleva tiedosto on todella olemassa. Puuttuvien paljaiden pakettien tai virheellisten pakettien yhdistämismääritysten tapauksessa itse ratkaisu voi silti paljastaa virheen aiemmin.
Pitäisikö node_modules ja lockfile poistaa?
Ei ensimmäisenä vastauksena. Puuttuvaa laajennusta, väärää paikallista polkua tai tukematonta paketin alipolkua ei korjata asentamalla riippuvuuksia uudelleen.
Jos npm lsraportoi epäjohdonmukaisesta puusta, projektilla on commited-tiedosto package-lock.jsonja haluat toistettavan puhtaan asennuksen, käytä:
npm ci
Nykyisessä npm ci -dokumentaatiossa todetaan, että npm civaatii olemassa olevan lukitustiedoston, poistaa olemassa olevan node_moduleshakemiston automaattisesti, asentaa lukitun puun eikä kirjoita package.jsonlukitustiedostoa uudelleen. Jos package.jsonja lukitustiedosto ovat ristiriidassa, ohjelma sulkeutuu lukituksen hiljaisen päivittämisen sijaan.
Vältä poistamista package-lock.jsonvain virheen katoamiseksi. Se voi aiheuttaa uuden riippuvuusgraafin syntymisen ja muuttaa moduulin ratkaisuvirheen riippuvuusversion muutokseksi.
Mikä on nopein vianmääritysjärjestys?
Mitä virheen nimet ovat
Tarkista ensin
Tyypillinen korjaus
./local/path
Tarkka polku ja jatko
Lisää .js/ .mjsja korjaa suhteellinen polku
Hakemisto
Odotitko sittenkinindex.js
Tuo ./directory/index.jseksplisiittisesti
package-name
npm ls package-name
Asenna tai määritä riippuvuus oikein
package-name/subpath
Paketti "exports"ja viralliset pakkausdokumentit
Käytä vietyä julkista alipolkua
Oikealta näyttävä polku
Tiedostonimen kirjainkoko ja varsinainen projektipuu
Vastaa tiedostojärjestelmää täsmälleen
Vain yksi ympäristö epäonnistuu
Lukitustiedosto, työtila, solmun versio, tiedostojärjestelmän tapaus
Kopioi samalla ilmoitetulla riippuvuuspuulla
Mitä sokeasti muutettaessa kannattaa välttää?
Älä lisää "type": "module"vain siksi, että tuonti epäonnistui; vahvista ensin projektin tarkoitettu moduulijärjestelmä.
Älä poista tiedostopäätteitä jäljitelläksesi CommonJS-esimerkkejä. Node.js ESM vaatii eksplisiittiset tiedostopäätteet suhteellisille ja absoluuttisille tiedostomäärittelijöille.
Älä syvätuo yksityisiä tiedostoja riippuvuudesta, jos sen "exports"kartta tarjoaa tuetun julkisen aloituspisteen.
Älä oleta, että onnistunut globaali npm-asennus tekee riippuvuuden saataville paikalliselle sovellukselle.
Älä poista lukitustiedostoa osana rutiininomaista välimuistin puhdistusta.
Älä oleta, että työhakemisto ohjaa suhteellisia ESM-tuointeja; tuontimoduuli on perusta.
Mistä tiedät, että korjaus on valmis?
Suorita uudelleen sama aloituskohta, josta alun perin epäonnistui, ja varmista, että moduuli korjaa virheen korvaamatta sitä toisella ratkaisuongelmalla. Suorita sitten projektin normaalit testit tai käynnistyskomento, jotta tiedät, että korjaus toimii yhden import-lausekkeen lisäksi.
Kun olet korjannut taustalla olevan ratkaisuongelman, suorita alkuperäinen komento uudelleen ja sitten projektin normaali testi- tai käynnistystyönkulku.
Jos sovellus saavuttaa nyt toisen virheen, kuten ERR_PACKAGE_PATH_NOT_EXPORTED, ERR_UNKNOWN_FILE_EXTENSIONtai viennin nimen virheen, älä käsittele sitä samana ongelmana. Se tarkoittaa, että moduulin ratkaisu on edennyt pidemmälle ja Node.js raportoi nyt tarkemmasta yhteensopimattomuusongelmasta.
Lopputulos
Node.js ESM:ssä ERR_MODULE_NOT_FOUNDongelma ratkaistaan yleensä jäljittämällä tarkka määrite sen sijaan, että asentaisit kaiken uudelleen. Paikalliset tiedostot tarvitsevat eksplisiittiset tiedostopäätteet ja eksplisiittiset hakemistoindeksit. Paljaat paketit on asennettava oikeaan riippuvuuspuuhun. Pakettien alipolkujen on noudatettava "exports". Ohjausjärjestelmän package.jsonon vastattava aiottua moduulijärjestelmää ja tiedostonimien on vastattava täsmälleen tiedostojärjestelmää.
Kun lähestyt virhettä tässä järjestyksessä – määritteen tyyppi, todellinen polku, ESM-säännöt, riippuvuuspuu, pakettien viennit ja sitten puhdas asennus – voit yleensä tunnistaa syyn nopeasti tekemättä epäolennaisia muutoksia.