Modul nicht gefunden: Fehlersuche bei Express-Imports und Routenparametern
Eine TypeScript Express-Wetter-API versagt aufgrund eines fehlenden Controller-Imports. Prüfen Sie die Pfadangaben, Groß-/Kleinschreibung sowie Exporte und validieren Sie anschließend :city, bevor Sie auf Live-Wetter-APIs zugreifen.
Das Debuggen einer TypeScript-Express-Wetter-API lehrt oft mehr darüber, wie ein Node-Backend zusammenwirkt, als eine weitere abstrakte Anleitung zu REST.
Der Fehler
Nachdem das Projekt in Routen und Controller aufgeteilt wurde, fiel der Server mit folgendem Fehler aus:
Cannot find module '../controllers/weatherController'
Diese Meldung tritt häufig auf, wenn ein Backend aus mehreren Dateien besteht. Express importiert weatherController, doch der Laufzeitumgebung ist dieser Modulpfad nicht bekannt.
Was überprüfen?
Gehen Sie in einer festgelegten Reihenfolge den Fehler durch, anstatt zu raten.
Gibt es die Datei? Unter src/ sollte der Ordnerstruktur Folgendes enthalten:
src/
├── controllers/
│ └── weatherController.ts
Stimmt der Ordnername genau? Verwenden Sie lieber controllers anstelle von controller oder Controllers. Sowohl die Pluralform als auch die Großschreibung sind auf kasusempfindlichen Dateisystemen wichtig.
Stimmt der Dateinamen genau überein? Es sollte weatherController.ts sein – nicht WeatherController.ts, weathercontroller.ts oder weather-controller.ts. Die Modulauflösung in TypeScript betrachtet diese als unterschiedliche Ziele.
Ist der Importpfad korrekt? In weatherRoutes.ts sieht die Verknüpfung von Importen und Routen wie folgt aus:
import { Router } from "express";
import { getWeather } from "../controllers/weatherController";
const router = Router();router.get("/:city", getWeather);export default router;
Exportiert der Controller tatsächlich die Funktion? Ein häufiger Fehler ist das Schreiben des Handlers ohne export, wodurch der Routenimport nichts zum Binden hat.
import { Request, Response } from "express";
export const getWeather = (req: Request, res: Response): void => {
const { city } = req.params; res.json({
city,
temperature: 29,
condition: "Cloudy",
humidity: 82,
});
};
Durch Hinzufügen von export vor getWeather funktionierte der Server wieder. Ein Schlüsselwort, ein behobener Fehler.
Was das Projekt bisher umfasst
An diesem Kontrollpunkt enthält der Wetterdienst bereits mehrere Elemente im Produktformat:
- Eine TypeScript-Toolkette für das Repository
- Einen laufenden Express-HTTP-Prozess
- Trennte Verzeichnisse anstelle einer einzigen Mega-Datei
- URL-Routen, die mit Handlern verbunden sind
- Handler-Module für die Anfragenlogik
- Pfadparameter wie
:city - Gestrukturierte JSON-Datenpakete
- Einen Fehler bei fehlenden Modulen, der durch lokale Überprüfung von Pfaden und Exporten behoben wird
Verständnis der Routenparameter
Testen Sie die Route über einen HTTP-Client wie Postman:
GET http://localhost:3000/weather/bangalore
GET http://localhost:3000/weather/mumbai
GET http://localhost:3000/weather/chennai
Jede Antwort ändert das Feld city. Die Struktur bleibt unverändert: temperature, condition und humidity sind weiterhin vorhanden. Der Stadtname stammt vom Pfadteil nach /weather/ und wird als req.params.city bereitgestellt. Darin besteht der Sinn eines Route-Parameters: eine einzige Routendefinition, wobei pro Anfrage mehrere Werte eingesetzt werden können.
Die nächste Herausforderung: grundlegende Validierung
Eine Anfrage wie die folgende funktioniert trotzdem mit simulierten Daten:
GET /weather/123
und gibt etwas wie folgt zurück:
{
"city": "123",
"temperature": 29,
"condition": "Cloudy",
"humidity": 82
}
Ein Stadtname sollte nicht nur aus Ziffern bestehen. Solche Fälle sollten abgelehnt werden anstelle dessen, sie als gültige Wetterdaten zu behandeln.
Prüfen Sie den Stadtnamen-Parameter mit /^\d+$/. Bei einer vollständigen Übereinstimmung sollte mit 400 Bad Request geantwortet werden, anstatt simulierter Wetterdaten zu liefern:
res.status(400).json({
error: "City name must contain letters.",
});
Andernfalls wird die normale Wetterdatenmenge zurückgegeben. Die Überprüfung vor dem Abrufen einer vorgefertigten Antwort sorgt dafür, dass die Regel besser eingehalten wird als durch das Einfügen eines fertigen Fragments.
Schnelle Wissensprüfung
Eine kurze Selbstfragestunde bestätigt die Konzepte, anstatt nur auf einen glücklichen Kompilierungsprozess zu vertrauen:
1. Worin unterscheidet sich GET /weather/:city von GET /weather?city=bangalore? Die Pfadsegmente verwenden erforderliche Route-Parameter, die direkt im URL-Muster enthalten sind. Werte nach ? sind Abfrageparameter und bleiben optional. Verwenden Sie Route-Parameter, wenn der Wert die Ressource identifiziert; verwenden Sie Abfrageparameter für Filter und Schalter.
2. Warum sollte man res.status(400).json() anstatt nur res.json() verwenden? Allein verwendet res.json() standardmäßig den Status 200 OK. Für ungültige Eingaben ist ein Status erforderlich, der einen Fehler anzeigt, nicht nur eine Fehlermeldung im Inhalt. Die Clients verlassen sich auf diesen Statuscode.
3. Welcher Schicht gehören die Geschäftsregeln an – dem Router, dem Controller oder anderswo? Legen Sie die Regeln in den Controllern fest. Router verbinden lediglich die HTTP-Methode und den Pfad mit einem Handler. Validierung sowie Aufrufe an externe Dienste finden zunächst im Controller statt und wechseln bei Wachstum der Anwendung in ein Service-Modul.
4. Was enthält req.params.city für GET /weather/mumbai? Den String "mumbai", genau so, wie er im Pfad eingegeben wurde.
Was kommt als Nächstes
Die simulierten Wetterdaten haben ihre Aufgabe erfüllt. Die nächste Schicht ist eine echte Wetter-API, was Folgendes bedeutet:
- Aufruf einer externen HTTP-API
- Umgebungsvariablen (
.env), damit Schlüssel niemals direkt im Quellcode festgeschrieben sind - Nutzung von
fetchoderaxiosfür den Ausgangsanfragen - Klare Handhabung von Zeitüberschreitungen und Fehlern bei der Verbindung zum Server
- Eine Services-Ordnerstruktur, damit die Controller nicht für die Arbeit mit dem HTTP-Client verantwortlich sind
Der Anfragepfad erhält eine weitere Schicht:
Browser/Postman
│
▼
Routes
│
▼
Controllers
│
▼
Services
│
▼
Weather API (external)
Diese schichtweise Struktur entspricht vielen produktiven Express-Anwendungen. Durch schrittweises Aufbauen bleibt bei Störungen in der Live-Integration ein klarer Punkt für einen Rollback vorhanden, anstatt alle Aufgaben in einer einzigen Datei zu bündeln.