Hur man åtgärdar "ERR_MODULE_NOT_FOUND" i Node.js ESM-importer

ERR_MODULE_NOT_FOUNDbetyder att Node.js nådde ECMAScript-modulladdaren och kunde inte lösa modulen som begärdes av en import, import(), eller programstartpunkten. I den aktuella Node.js-dokumentationen definieras detta fel specifikt som ett ESM-laddarlösningsfel; det analoga CommonJS-felet är MODULE_NOT_FOUND. Se den officiella Node.js-felreferensen .

Den snabbaste lösningen är att identifiera vilken typ av specifikation som misslyckades innan något ändras. En relativ import som ./utils/logger.jsföljer andra regler än en paketimport som lodash. Node.js ESM löses också annorlunda än CommonJS: relativa importer kräver explicita filändelser och katalogindex gissas inte automatiskt. Dessa skillnader förklarar många fel efter övergången från require()till import.

Vad exakt är det Node.js inte hittar?

Börja med den första raden i felet, inte hela stackspårningen. Den visar normalt både det olösta målet och filen som försökte importera det. Klassificera den felaktiga specificeraren i en av dessa grupper:

  • Relativ fil: ./utils/logger.js eller ../config.js.
  • Absolut fil eller fil-URL: en absolut sökväg eller file:URL.
  • Barförpackning: lodash , express, eller @scope/pkg.
  • Paketets undersökväg: some-package/feature.js .
  • Paketimportalias: en intern specifikation som börjar med #, definierad genom package.json "imports".
Terminalen visar Node.js ERR_MODULE_NOT_FOUND för ett saknat lodash-paket
Läs den första felraden först: det här exemplet identifierar ett rent paketnamn, så nästa kontroller bör fokusera på beroendeinstallation och paketlösning.

Den officiella dokumentationen för Node.js ECMAScript-moduler separerar relativa, nakna och absoluta specifikationer eftersom de inte löses på samma sätt. När du väl vet vilken kategori som misslyckades, undvik slumpmässiga korrigeringar som att ta bort node_moduleseller ändra package.jsontills bevisen pekar dit.

Inkluderar en lokal ESM-import den verkliga filändelsen?

För relativa och absoluta ESM-specifikationer kräver Node.js filändelsen. Den söker inte efter .js, .mjseller .jsonefter en misslyckad relativ import. Den nuvarande Node.js-dokumentationen kallar denna regel obligatoriska filändelser och anger också att katalogindex måste vara fullständigt specificerade.

Om filen på disken är src/utils/logger.js, är detta den säkra ESM-formen:

import { logger } from './utils/logger.js';

Inte:

import { logger } from './utils/logger';
Kodredigerare som jämför en ESM-import utan tillägg med en import som slutar på .js
Node.js ESM utför inte filändelsesökning för relativa importer. Skriv det faktiska filändelsen i modulspecifikationen.

Detta är en av de viktigaste skillnaderna från CommonJS-upplösningen. Den officiella dokumentationen för Node.js-paket förklarar att require()man kan testa tillägg och mappar, medan ESM-laddaren inte utför någon sökning efter tillägg.

Importerar du en katalog istället för en faktisk fil?

Ett CommonJS-projekt kan ha förlitat sig på en katalogimport som så småningom laddade en index.js. Anta inte att ESM-laddaren kommer att göra detsamma. Om din struktur är:

src/
  config/
    index.js
  app.js

föredra:

import config from './config/index.js';

snarare än:

import config from './config';
Terminalen visar ERR_MODULE_NOT_FOUND för en import av lokala verktyg utan tillägg
Ett lokalt lösningsfel pekar vanligtvis på den exakta olösta sökvägen. Kontrollera sökvägen, filändelsen och om importen är riktad mot en katalog snarare än en fil.

Den officiella ESM-dokumentationen anger att katalogindex som ./startup/index.jsmåste vara fullständigt specificerade. Om tillägget av tillägget fortfarande misslyckas, jämför varje sökvägssegment med det faktiska katalogträdet.

Körs projektet verkligen som ESM?

Node.js stöder både CommonJS- och ECMAScript-moduler. För .jsfiler är den tydligaste markören på paketnivå:

{
  "type": "module"
}

Filer som slutar på .mjsbehandlas alltid som ES-moduler, medan filer som slutar på .cjsalltid behandlas som CommonJS. Nuvarande Node.js-versioner kan också upptäcka ESM-syntax i vissa tvetydiga filer, men Node.js-dokumentationen rekommenderar explicita paketmarkörer eftersom de är tydligare för Node.js, verktyg och framtida underhåll.

Package.json-redigeraren som visar typmodulen och en beroendepost
Kontrollera närmaste kontrollerande package.json. Ett överordnat typvärde för module gör att .js-filer i det paketet använder ESM-semantik.

Läs de officiella reglerna för paket och modultyper innan du ändrar "type". Att ändra ett paket från CommonJS till ESM kan påverka många filer samtidigt. Kom också ihåg att tillägg "type": "module"inte installerar ett saknat beroende eller korrigerar en felaktig sökväg; det avgör bara hur relevanta .jsfiler tolkas.

Är det saknade paketet faktiskt installerat i det här projektet?

Om felet namnger ett naket paket som lodash, kontrollera beroendeträdet istället för att anta att ett globalt installerat paket eller en annan arbetsyta gör det tillgängligt.

npm ls lodash

Den nuvarande npm-dokumentationen för npm ls säger att kommandot listar installerade paketversioner och kan rapportera saknade eller ogiltiga beroenden. Om paketet är ett direkt runtime-beroende och inte är installerat, installera det i rätt projekt:

npm install lodash
Terminalen visar npm-listan lodash som returnerar tom och npm install lodash lägger till paketet
För import av ett naket paket, verifiera att paketet finns i det aktuella beroendeträdet innan du ändrar ESM-syntaxen.

Den officiella npm-installationsdokumentationen förklarar att en normal projektinstallation placerar beroenden i det lokala node_modulesträdet och som standard sparar explicit installerade paket till dependencies.

I ett monorepo, kör kontrollen i arbetsytan som äger importfilen. Att ett paket installeras någon annanstans i repositoriet betyder inte automatiskt att det aktuella paketet har ett giltigt deklarerat beroende.

Är paketnamnet rätt, men undersökvägen fel?

Ett paket kan existera och ändå avvisa en djup import. Moderna paket kan definiera en "exports"karta i sin package.json. När det fältet finns tillåter Node.js endast de publika entrypunkter som deklareras där. Den officiella Node.js package-entry-point-dokumentationen säger "exports"att har företräde framför "main"i stödda Node.js-versioner och inkapslar olistade undersökvägar.

Anta att ett beroende dokumenterar denna publika import:

import { parse } from 'example-package/parser';

Ersätt den inte med en gissad intern sökväg som:

import { parse } from 'example-package/dist/internal/parser.js';
Package.json-redigeraren som visar ett ESM-paket och ett lodash-beroende
Kontrollera metadata för installerat paket när ett naket paket matchas men en undersökväg inte gör det. Offentliga undersökvägar styrs av paketets exportkarta när en sådan finns.

En blockerad "exports"undersökväg producerar ofta ERR_PACKAGE_PATH_NOT_EXPORTEDsnarare än ERR_MODULE_NOT_FOUND. Den förändringen i felkoden är ett användbart bevis: det betyder att Node.js hittade paketet men den begärda sökvägen är inte en del av dess publika gränssnitt. Använd paketets dokumenterade importsökväg istället för att kringgå inkapsling.

Kan sökvägen skilja sig endast genom stavning eller versaler/versaler?

Kontrollera det faktiska filträdet för tecken. Importer som verkar fungera på ett utvecklingsfilsystem som inte är skiftlägeskänsligt kan misslyckas efter distribution till ett filsystem som är skiftlägeskänsligt.

Till exempel, om den riktiga filen är:

src/utils/Logger.js

sedan en import av:

import logger from './utils/logger.js';

är inte portabel, eftersom Logger.jsoch logger.jskan ha olika filnamn.

Projektutforskaren visar en src-katalog med utils, helper.js, index.js och app.js
Jämför importen med det verkliga katalogträdet. Kontrollera alla mappnamn, filnamn, tillägg och versaler.

Kontrollera också att importen är relativ till importmodulen , inte till skalets aktuella katalog. ESM:s relativa specifikationer tolkas relativt till modul-URL:en för importfilen.

Hur kan du se vad Node.js skulle lösa?

I en ES-modul import.meta.resolve()kan följande hjälpa till att inspektera upplösningen:

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

Den officiella Node.js ESM-referensen beskriver den import.meta.resolve(specifier)som en modul-relativ upplösningsfunktion som returnerar en absolut URL-sträng och respekterar paketupplösning och tillåtna exporter.

Det finns en viktig varning gällande den aktuella versionen: för ett relativt file:mål import.meta.resolve()kan URL:en returneras även när motsvarande lokala fil inte finns. Använd den för att svara på frågan "Vilket mål löser noden denna specifikation till?" och verifiera sedan att den resulterande filen faktiskt finns. För saknade nakna paket eller ogiltiga paketmappningar kan själva lösningen fortfarande avslöja felet tidigare.

Bör du ta bort node_modules och lockfilen?

Inte som det första svaret. Ett saknat tillägg, fel lokal sökväg eller en paketundersökväg som inte stöds kommer inte att repareras genom att ominstallera beroenden.

Om npm lsdet rapporteras ett inkonsekvent träd, projektet har en committed package-lock.json, och du vill ha en reproducerbar ren installation, använd:

npm ci

Den nuvarande npm ci-dokumentationen anger att den npm cikräver en befintlig låsfil, tar bort den befintliga node_moduleskatalogen automatiskt, installerar det låsta trädet och skriver inte package.jsonom låsfilen. Om package.jsonoch låsfilen inte överensstämmer avslutas den istället för att tyst uppdatera låset.

Undvik att radera package-lock.jsonbara för att felet ska försvinna. Det kan orsaka att ett nytt beroendediagram löses och förvandla ett modulupplösningsfel till en ändring av beroendets version.

Vilken är den snabbaste felsökningsordningen?

Vad felet heterKontrollera förstTypisk fix
./local/pathExakt sökväg och förlängningLägg till .js/ .mjsoch korrigera den relativa sökvägen
En katalogOavsett om du förväntade digindex.jsImportera ./directory/index.jsexplicit
package-namenpm ls package-nameInstallera eller deklarera beroendet korrekt
package-name/subpathPaket "exports"och officiell paketdokumentationAnvänd en exporterad offentlig undersökväg
En väg som ser rätt utFilnamnsfall och faktiskt projektträdMatcha filsystemet exakt
Endast en miljö misslyckasLåsfil, arbetsyta, nodversion, filsystemsfallReproducera med samma deklarerade beroendeträd

Vad bör du undvika att ändra blint?

  • Lägg inte till "type": "module"bara för att en import misslyckades; bekräfta först projektets avsedda modulsystem.
  • Ta inte bort filändelser för att imitera CommonJS-exempel. Node.js ESM kräver explicita filändelser för relativa och absoluta filspecifikationer.
  • Djupimportera inte privata filer från ett beroende när dess "exports"mappning tillhandahåller en offentlig startpunkt som stöds.
  • Anta inte att en lyckad global npm-installation gör ett beroende tillgängligt för en lokal applikation.
  • Ta inte bort en låsfil som ett rutinmässigt steg för cachens rensning.
  • Anta inte att arbetskatalogen styr relativa ESM-importer; importmodulen är basen.

Hur vet du att reparationen är klar?

Kör samma startpunkt som ursprungligen misslyckades igen och bekräfta att modulen löses utan att ersätta felet med ett annat lösningsproblem. Kör sedan projektets vanliga tester eller startkommando så att du vet att åtgärden fungerar utöver en enda import-sats.

Terminal som visar en paketinstallation följt av en lyckad Node.js-körning
När du har åtgärdat det underliggande lösningsproblemet, kör om det ursprungliga kommandot och sedan projektets normala test- eller startarbetsflöde.

Om programmet nu får ett annat fel, till exempel ERR_PACKAGE_PATH_NOT_EXPORTED, ERR_UNKNOWN_FILE_EXTENSION, eller ett export-name-fel, ska du inte behandla det som samma problem. Det betyder att modulupplösningen har fortskridit ytterligare och att Node.js nu rapporterar en mer specifik inkompatibilitet.

Slutsats

För Node.js ESM ERR_MODULE_NOT_FOUNDlöses det vanligtvis genom att spåra den exakta specificeraren snarare än att ominstallera allt. Lokala filer behöver explicita tillägg och explicita katalogindex. Paket utan attribut måste installeras i rätt beroendeträd. Paketets undersökvägar måste respektera "exports". Kontrollerna package.jsonmåste matcha det avsedda modulsystemet och filnamnen måste matcha filsystemet exakt.

När du närmar dig felet i den ordningen – specificeringstyp, verklig sökväg, ESM-regler, beroendeträd, paketexporter och sedan ren installation – kan du vanligtvis snabbt identifiera orsaken utan att införa orelaterade ändringar.

Lämna en kommentar

Hur man åtgärdar "Tailwind CSS-stilar uppdateras inte" i en Vite React-app

Hur man åtgärdar "Tailwind CSS-stilar uppdateras inte" i en Vite React-app

Åtgärda Tailwind CSS-stilar som inte uppdateras i Vite React genom att kontrollera Tailwind v4-inställningar, CSS-importer, källkodsidentifiering, dynamiska klasser, HMR och inaktuella cacher.

Så här åtgärdar du ModuleNotFoundError: Ingen modul med namnet 'pip' i Python 3

Så här åtgärdar du ModuleNotFoundError: Ingen modul med namnet 'pip' i Python 3

Åtgärda Python 3:s ModuleNotFoundError för pip på Windows, macOS och Linux med ensurepip, OS-paket, virtuella miljöer och tolkkontroller.

Hur man åtgärdar "Tillstånd nekad (publickey)" i GitHub SSH

Hur man åtgärdar "Tillstånd nekad (publickey)" i GitHub SSH

Åtgärda GitHub SSH-behörighet nekad (publickey) genom att kontrollera värden, aktiv SSH-nyckel, GitHub-konto, SSO-auktorisering, fjärr-URL och port 22-åtkomst.

Hur man åtgärdar "Git Push Rejected: Non-Spolar framåt" utan att förlora ändringar

Hur man åtgärdar "Git Push Rejected: Non-Spolar framåt" utan att förlora ändringar

Åtgärda en Git-push som inte snabbspolar framåt på ett säkert sätt. Skydda lokalt arbete, hämta fjärrcommits, välj merge eller rebase, lös konflikter och pusha utan att förlora ändringar.

Hur man åtgärdar "Nginx 502 Bad Gateway" vid proxyanvändning till Node.js

Hur man åtgärdar "Nginx 502 Bad Gateway" vid proxyanvändning till Node.js

Åtgärda Nginx 502 Bad Gateway-fel med en Node.js-uppström genom att kontrollera appporten, NGINX-loggarna, proxy_pass-adressen, containernätverk, timeouts och omladdning.

How to Fix “Type 'null' Is Not Assignable to Type” in TypeScript

How to Fix “Type 'null' Is Not Assignable to Type” in TypeScript

Fix TypeScript's “Type 'null' is not assignable to type” error with union types, narrowing, defaults, and safe assertions under strictNullChecks.

Så här åtgärdar du felet ”Prisma Client has not been generated yet”

Så här åtgärdar du felet ”Prisma Client has not been generated yet”

Åtgärda felet att Prisma Client inte har genererats genom att kontrollera din generator, ditt schema, utdatasökvägen, importerna, versionerna, monorepo-konfigurationen och byggstegen vid distribution.

Hur man åtgärdar "ERR_MODULE_NOT_FOUND" i Node.js ESM-importer

Hur man åtgärdar "ERR_MODULE_NOT_FOUND" i Node.js ESM-importer

Åtgärda Node.js ERR_MODULE_NOT_FOUND i ESM genom att kontrollera importsökvägar, filtillägg, paketinstallation, exporter, ESM-läge och rena installationer.

Så här åtgärdar du SSL-certifikatproblemet: Unable to Get Local Issuer Certificate i Git

Så här åtgärdar du SSL-certifikatproblemet: Unable to Get Local Issuer Certificate i Git

Åtgärda Gits fel 'unable to get local issuer certificate' genom att identifiera förtroendebakgrunden, installera rätt CA-kedja och hålla SSL-verifieringen aktiverad.

Så åtgärdar du MongoDB-nätverksavbrott vid Mongoose-anslutning

Så åtgärdar du MongoDB-nätverksavbrott vid Mongoose-anslutning

Åtgärda MongoDB-nätverksavbrott i Mongoose genom att identifiera avbrottstypen, testa Atlas- eller TCP-anslutning, korrigera URI:n och justera tidsgränser endast när det är motiverat.