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".
Terminal viser Node.js ERR_MODULE_NOT_FOUND for en manglende lodash-pakke
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';
Kodeeditor, der sammenligner en ESM-import uden udvidelse med en import, der ender på .js
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';
Terminal viser ERR_MODULE_NOT_FOUND for en import af lokale værktøjer uden udvidelse
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.

Package.json-editor, der viser typemodul og en afhængighedspost
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
Terminal viser npm-liste lodash, der returnerer tom, og npm install lodash tilføjer pakken
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';
Package.json-editor, der viser en ESM-pakke og en lodash-afhængighed
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.

Projekt Explorer, der viser en src-mappe med utils, helper.js, index.js og app.js
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:

console.log(import.meta.resolve('./utils/logger.js'));
console.log(import.meta.resolve('lodash'));

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.

Hvad er den hurtigste fejlfindingsrækkefølge?

Hvad fejlen hedderTjek førstTypisk løsning
./local/pathPræcis sti og udvidelseTilføj .js/ .mjsog ret den relative sti
En mappeOm du forventedeindex.jsImportér ./directory/index.jseksplicit
package-namenpm ls package-nameInstaller eller deklarer korrekt afhængigheden
package-name/subpathPakke "exports"og officielle pakkedokumenterBrug en eksporteret offentlig understi
En sti der ser rigtig udFilnavnssag og faktisk projekttræMatch filsystemet præcist
Kun ét miljø fejlerLåsefil, arbejdsområde, nodeversion, filsystemtilfældeReproducer 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.

Terminal viser en pakkeinstallation efterfulgt af en vellykket Node.js-kørsel
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.

Efterlad en kommentar

Sådan rettes "Type 'null' kan ikke tildeles til type" i TypeScript

Sådan rettes "Type 'null' kan ikke tildeles til type" i TypeScript

Retter TypeScripts fejl "Type 'null' kan ikke tildeles til type" med foreningstyper, indsnævring, standardværdier og sikre påstande under strictNullChecks.

Sådan retter du fejlen "Prisma Client Has Not Been Generated Yet"

Sådan retter du fejlen "Prisma Client Has Not Been Generated Yet"

Ret fejlen med Prisma Client, der ikke er genereret, ved at kontrollere din generator, schema, output-sti, imports, versioner, monorepo-opsætning og build-trin til deployment.

Sådan rettes "ERR_MODULE_NOT_FOUND" i Node.js ESM-importer

Sådan rettes "ERR_MODULE_NOT_FOUND" i Node.js ESM-importer

Ret Node.js ERR_MODULE_NOT_FOUND i ESM ved at kontrollere importstier, filtypenavne, pakkeinstallation, eksport, ESM-tilstand og rene installationer.

Sådan løser du SSL-certifikatproblemet: Unable to get local issuer certificate i Git

Sådan løser du SSL-certifikatproblemet: Unable to get local issuer certificate i Git

Løs Git-fejlen 'unable to get local issuer certificate' ved at identificere tillidsbackenden, installere den korrekte CA-kæde og holde SSL-verifikation aktiveret.

Sådan løser du MongoDB-netværkstidsudløbsfejl i Mongoose-forbindelsen

Sådan løser du MongoDB-netværkstidsudløbsfejl i Mongoose-forbindelsen

Løs MongoDB-netværkstidsudløbsfejl i Mongoose ved at identificere typen af tidsudløb, teste Atlas- eller TCP-tilgængelighed, korrigere URI'en og justere tidsudløb kun, når det er berettiget.

Sådan løser du Execution Policy Restricted-fejlen i Windows PowerShell

Sådan løser du Execution Policy Restricted-fejlen i Windows PowerShell

Løs PowerShell Execution Policy Restricted-fejlen ved at tjekke omfang og gruppepolitik, og vælg derefter RemoteSigned, Unblock-File eller en midlertidig sessionsindstilling.

Sådan løser du npm ERR! code ERESOLVE Peer Dependency-konflikt

Sådan løser du npm ERR! code ERESOLVE Peer Dependency-konflikt

Løs npm ERESOLVE peer dependency-konflikter ved at identificere det inkompatible pakkeområde, justere versioner, bruge npm explain og npm ls, og kun bruge legacy-peer-deps eller force som kontrollerede nødløsninger.

Sådan løser du fejlen 'Redis Connection to 127.0.0.1:6379 Failed'

Sådan løser du fejlen 'Redis Connection to 127.0.0.1:6379 Failed'

Løs Redis-forbindelsesfejl på 127.0.0.1:6379 ved at tjekke serveren, porten, Docker-netværk, redis.conf, godkendelse og TLS.

Sådan løser du intern fejl 500 i Next.js Server Components

Sådan løser du intern fejl 500 i Next.js Server Components

Løs 500-fejl i Next.js Server Components ved at spore serverlogs, tjekke datahentninger og miljøvariabler, håndtere fejl og verificere produktionsbygningen.

Sådan løser du Kubernetes CrashLoopBackOff i lokal Minikube

Sådan løser du Kubernetes CrashLoopBackOff i lokal Minikube

Diagnose og reparer Kubernetes CrashLoopBackOff i lokal Minikube ved at tjekke pod-tilstand, tidligere logs, afslutningsårsager, probes, konfiguration, hukommelsesgrænser og klyngesundhed.