Hjem
» Basis viden
»
Sådan rettes "ERR_MODULE_NOT_FOUND" i Node.js ESM-importer
Sådan rettes "ERR_MODULE_NOT_FOUND" i Node.js ESM-importer
ERR_MODULE_NOT_FOUNDbetyder, at Node.js nåede ECMAScript-modulindlæseren og ikke kunne løse det modul, der blev anmodet om af en import, import()eller programindgangspunkt. I den nuværende Node.js-dokumentation er denne fejl specifikt defineret som en ESM-indlæserløsningsfejl; den analoge CommonJS-fejl er MODULE_NOT_FOUND. Se den officielle Node.js-fejlreference .
Den hurtigste løsning er at identificere, hvilken type specifikation der fejlede, før noget ændres. En relativ import som f.eks. ./utils/logger.jsfølger andre regler end en pakkeimport som f.eks lodash. Node.js ESM løses også anderledes end CommonJS: relative importer kræver eksplicitte filtypenavne, og mappeindekser gættes ikke automatisk. Disse forskelle forklarer mange fejl efter flytning fra require()til import.
Hvad er det præcist, Node.js ikke kan finde?
Start med den første linje i fejlen, ikke hele staksporingen. Den viser normalt både det uløste mål og den fil, der forsøgte at importere det. Klassificer den fejlende specifikation i en af disse grupper:
Relativ fil:./utils/logger.js eller ../config.js.
Absolut fil eller fil-URL: en absolut sti eller file:URL.
Bar pakke:lodash , express, eller @scope/pkg.
Pakkeundersti:some-package/feature.js .
Pakkeimportalias: en intern specifikation, der starter med #, defineret via package.json"imports".
Læs den første fejllinje først: dette eksempel identificerer et rent pakkenavn, så de næste kontroller bør fokusere på installation af afhængigheder og pakkeløsning.
Den officielle dokumentation for Node.js ECMAScript-moduler adskiller relative, bare og absolutte specifikationer, fordi de ikke løses på samme måde. Når du ved, hvilken kategori der fejlede, skal du undgå tilfældige rettelser såsom sletning node_moduleseller ændring, package.jsonindtil beviserne peger imod.
Inkluderer en lokal ESM-import den rigtige filtypenavnelse?
For relative og absolutte ESM-specifikationer kræver Node.js filtypen. Den søger ikke efter .js, .mjseller .jsonefter en mislykket relativ import. Den nuværende Node.js-dokumentation kalder denne regel obligatoriske filtypender og angiver også, at mappeindekser skal være fuldt specificerede.
Hvis filen på disken er src/utils/logger.js, er dette den sikre ESM-formular:
import { logger } from './utils/logger.js';
Ikke:
import { logger } from './utils/logger';
Node.js ESM udfører ikke søgning efter filtypenavne for relative importer. Skriv den faktiske filtypenavn i modulspecifikationen.
Dette er en af de vigtigste forskelle fra CommonJS-opløsningen. Den officielle dokumentation for Node.js-pakker forklarer, at require()man kan prøve udvidelser og mapper, mens ESM-indlæseren ikke udfører søgning efter udvidelser.
Importerer du en mappe i stedet for en faktisk fil?
Et CommonJS-projekt kan have været afhængig af en mappeimport, der til sidst indlæste en index.js. Gå ikke ud fra, at ESM-indlæseren vil gøre det samme. Hvis din struktur er:
src/
config/
index.js
app.js
foretrække:
import config from './config/index.js';
snarere end:
import config from './config';
En lokal løsningsfejl peger normalt på den præcise uløste sti. Kontroller stien, filtypenavnet og om importen er rettet mod en mappe i stedet for en fil.
Den officielle ESM-dokumentation angiver, at mappeindekser som f.eks. ./startup/index.jsskal være fuldt specificerede. Hvis tilføjelsen af udvidelsen stadig mislykkes, skal du sammenligne hvert stisegment med det faktiske mappetræ.
Kører projektet virkelig som ESM?
Node.js understøtter både CommonJS- og ECMAScript-moduler. For .jsfiler er den tydeligste markør på pakkeniveau:
{
"type": "module"
}
Filer, der ender på , .mjsbehandles altid som ES-moduler, mens filer, der ender på , .cjsaltid behandles som CommonJS. Nuværende Node.js-versioner kan også registrere ESM-syntaks i nogle tvetydige filer, men Node.js-dokumentationen anbefaler eksplicitte pakkemarkører, fordi de er tydeligere for Node.js, værktøjer og fremtidig vedligeholdelse.
Tjek den nærmeste kontrollerende package.json. En topniveau-typeværdi for module får .js-filer i den pakke til at bruge ESM-semantik.
Læs de officielle regler for pakker og modultyper, før du ændrer dem "type". Ændring af en pakke fra CommonJS til ESM kan påvirke mange filer på én gang. Husk også, at tilføjelse "type": "module"ikke installerer en manglende afhængighed eller retter en forkert sti; det bestemmer kun, hvordan relevante .jsfiler fortolkes.
Er den manglende pakke rent faktisk installeret i dette projekt?
Hvis fejlen navngiver en bare pakke, f.eks. lodash, skal du kontrollere afhængighedstræet i stedet for at antage, at en globalt installeret pakke eller et andet arbejdsområde gør den tilgængelig.
npm ls lodash
Den nuværende npm-dokumentation til npm ls siger, at kommandoen viser installerede pakkeversioner og kan rapportere manglende eller ugyldige afhængigheder. Hvis pakken er en direkte runtime-afhængighed og ikke er installeret, skal du installere den i det korrekte projekt:
npm install lodash
Ved import af en ren pakke skal du kontrollere, at pakken er i det aktuelle afhængighedstræ, før du ændrer ESM-syntaksen.
Den officielle npm-installationsdokumentation forklarer, at en normal projektinstallation placerer afhængigheder i det lokale node_modulestræ og som standard gemmer eksplicit installerede pakker til dependencies.
I et monorepo skal du køre kontrollen i det arbejdsområde, der ejer den importerende fil. En pakke, der installeres et andet sted i repository'et, betyder ikke automatisk, at den aktuelle pakke har en gyldig, deklareret afhængighed.
Er pakkenavnet korrekt, men understien forkert?
En pakke kan eksistere og stadig afvise en dyb import. Moderne pakker kan definere et "exports"kort i deres package.json. Når dette felt findes, tillader Node.js kun de offentlige indgangspunkter, der er deklareret der. Den officielle Node.js package-entry-point-dokumentation siger, "exports"at har forrang "main"i understøttede Node.js-versioner og indkapsler ikke-listede understier.
Antag at en afhængighed dokumenterer denne offentlige import:
import { parse } from 'example-package/parser';
Erstat den ikke med en gættet intern sti, såsom:
import { parse } from 'example-package/dist/internal/parser.js';
Undersøg metadataene for den installerede pakke, når en bare pakke fortolkes, men en understi ikke gør. Offentlige understier styres af pakkens eksportkort, når et sådant findes.
En blokeret "exports"understi producerer ofte ERR_PACKAGE_PATH_NOT_EXPORTEDi stedet for ERR_MODULE_NOT_FOUND. Denne ændring i fejlkoden er et nyttigt bevis: det betyder, at Node.js fandt pakken, men den anmodede sti er ikke en del af dens offentlige grænseflade. Brug pakkens dokumenterede importsti i stedet for at omgå indkapsling.
Kunne stien kun afvige ved stavning eller store/små bogstaver?
Kontrollér det faktiske filtræ, tegn for tegn. Importer, der ser ud til at virke på et udviklingsfilsystem, der ikke skelner mellem store og små bogstaver, kan mislykkes efter implementering til et filsystem, der skelner mellem store og små bogstaver.
For eksempel, hvis den rigtige fil er:
src/utils/Logger.js
derefter en import af:
import logger from './utils/logger.js';
er ikke bærbar, fordi Logger.jsog logger.jskan have forskellige filnavne.
Sammenlign importen med det rigtige mappetræ. Bekræft alle mappenavne, filnavne, filendelser og store og små bogstaver.
Bekræft også, at importen er relativ til importmodulet og ikke til shells aktuelle mappe. ESM-relative specifikationer er opløst i forhold til modul-URL'en i den importerende fil.
Hvordan kan du se, hvad Node.js ville løse?
I et ES-modul import.meta.resolve()kan følgende hjælpe med at inspicere opløsning:
Den officielle Node.js ESM-reference beskriver den import.meta.resolve(specifier)som en modul-relativ opløsningsfunktion, der returnerer en absolut URL-streng og respekterer pakkeopløsning og tilladte eksporter.
Der er en vigtig advarsel vedrørende den nuværende version: for et relativt file:mål import.meta.resolve()kan URL'en returneres, selvom den tilsvarende lokale fil ikke findes. Brug den til at besvare "Hvilket mål løser noden denne specifikation til?", og verificer derefter, at den resulterende fil rent faktisk findes. For manglende pakker uden indhold eller ugyldige pakketilknytninger kan selve løsningen stadig afsløre fejlen tidligere.
Skal du slette node_modules og lockfilen?
Ikke som det første svar. En manglende udvidelse, forkert lokal sti eller en ikke-understøttet pakkeundersti vil ikke blive repareret ved at geninstallere afhængigheder.
Hvis npm lsder rapporteres et inkonsistent træ, projektet har en committed package-lock.json, og du ønsker en reproducerbar ren installation, skal du bruge:
npm ci
Den nuværende npm ci-dokumentation angiver, at den npm cikræver en eksisterende låsefil, fjerner den eksisterende node_modulesmappe automatisk, installerer det låste træ og ikke omskriver package.jsonlåsefilen. Hvis package.jsonog låsefilen ikke stemmer overens, afsluttes den i stedet for lydløst at opdatere låsen.
Undgå at slette package-lock.jsonblot for at få fejlen til at forsvinde. Det kan forårsage, at en ny afhængighedsgraf løses, og at en modulløsningsfejl forvandles til en ændring af afhængighedsversionen.
Reproducer med det samme deklarerede afhængighedstræ
Hvad skal du undgå at ændre blindt?
Tilføj ikke "type": "module"blot fordi en import mislykkedes; bekræft først projektets tilsigtede modulsystem.
Fjern ikke filtypenavne for at efterligne CommonJS-eksempler. Node.js ESM kræver eksplicitte filtypenavne for relative og absolutte filspecifikationer.
Undlad at dybimportere private filer fra en afhængighed, når dens "exports"tilknytning giver et understøttet offentligt indgangspunkt.
Antag ikke, at en vellykket global npm-installation gør en afhængighed tilgængelig for en lokal applikation.
Slet ikke en låsefil som et rutinemæssigt trin i cachens rydning.
Antag ikke, at arbejdsmappen styrer relative ESM-importer; importmodulet er grundlaget.
Hvordan ved du, at reparationen er fuldført?
Kør det samme indgangspunkt igen, der oprindeligt mislykkedes, og bekræft, at modulet løser problemet uden at erstatte fejlen med et andet løsningsproblem. Kør derefter projektets normale tests eller startup-kommando, så du ved, at løsningen virker ud over en enkelt import-sætning.
Når du har rettet det underliggende løsningsproblem, skal du køre den oprindelige kommando igen og derefter projektets normale test- eller opstartsarbejdsgang.
Hvis applikationen nu får en anden fejl, såsom ERR_PACKAGE_PATH_NOT_EXPORTED, ERR_UNKNOWN_FILE_EXTENSION, eller en export-name-fejl, skal du ikke behandle det som det samme problem. Det betyder, at modulopløsningen er skredet videre, og Node.js rapporterer nu en mere specifik inkompatibilitet.
Konklusion
For Node.js ESM ERR_MODULE_NOT_FOUNDløses det normalt ved at spore den nøjagtige specifikator i stedet for at geninstallere alt. Lokale filer kræver eksplicitte udvidelser og eksplicitte mappeindekser. Ubegrænsede pakker skal installeres i det korrekte afhængighedstræ. Pakkeunderstier skal respektere "exports". Kontrollerne package.jsonskal matche det tilsigtede modulsystem, og filnavnene skal matche filsystemet nøjagtigt.
Når du har adresseret fejlen i den rækkefølge – specifikationstype, reel sti, ESM-regler, afhængighedstræ, pakkeeksport og derefter ren installation – kan du normalt hurtigt identificere årsagen uden at introducere irrelevante ændringer.