Checkliste für Node.js Code Reviews: Alle Schritte enthalten

Node.js hat sich von einem kühnen Experiment zum Rückgrat der modernen Backend-Entwicklung entwickelt. Bis 2025 nutzen laut der Stack Overflow Developer Survey 48,7 % der Entwickler weltweit Node.js, was es zum am weitesten verbreiteten Web-Framework der Welt macht. Unternehmen wie Netflix, PayPal und Amazon betreiben kritische Infrastrukturen damit. Das npm-Ökosystem umfasst mittlerweile über 2 Millionen Pakete. Doch keine dieser Beliebtheit schützt eine Codebasis vor Problemen, die sich einschleichen, wenn niemand genau hinsieht.

Leider macht eine schnelle Laufzeit eine Anwendung weder sicher noch wartbar. Sie beschleunigt nur die Skalierung von Problemen. Deshalb ist eine strukturierte Code-Überprüfung eine der wichtigsten Investitionen, die ein Node.js-Team tätigen kann, egal ob Sie sich auf eine Finanzierungsrunde vorbereiten, ein neues Ingenieurteam einarbeiten oder ein Produkt versenden, das Sie die nächsten fünf Jahre unterstützen wollen.

Bei Redwerk bauen und überprüfen wir Node.js seit Jahren, und diese Checkliste spiegelt wider, worauf unsere Ingenieure bei jeder Überprüfung achten. Wir haben sie genauso organisiert, wie wir den Prozess selbst durchführen.

Vorbereitung vor der Überprüfung

Zunächst einmal ist es wie eine Verhandlung ohne Lektüre des Briefings, eine Überprüfung ohne Vorbereitung zu beginnen. Es bedeutet, dass Sie trotzdem etwas erreichen könnten, aber die wichtigsten Dinge verpassen.

Umfang und Ziele definieren:

  • Identifizieren Sie zunächst, ob die Überprüfung die gesamte Codebasis abdeckt oder ob Sie sich auf ein bestimmtes Modul, eine API-Schicht oder eine neuere Version konzentrieren
  • Legen Sie klare Erfolgskriterien fest. Das bedeutet, zu definieren, was eine erfolgreiche Überprüfung ausmacht. Sind es weniger Sicherheitsprobleme, eine bessere Testabdeckung oder verbesserte Antwortzeiten?
  • Notieren Sie bekannte Problembereiche, die vom Team hervorgehoben wurden, wie langsame Endpunkte, instabile Tests oder neu eingeführte Abhängigkeiten

Umgebung und Einrichtung überprüfen:

  • Bestätigen Sie, dass das Projekt sowohl im Entwicklungs- als auch im Produktionsmodus fehlerfrei und ohne Warnungen beim Start läuft
  • Prüfen Sie, ob die verwendete Node.js-Version mit der in .nvmrc oder .node-version festgelegten übereinstimmt und ob es sich um eine aktive LTS-Version handelt (24.x Active LTS (Krypton) vom 22.04.2025 bis 30.04.2028. 22.x Maintenance LTS (Jod) vom 24.04.2024 bis 30.04.2027. sind die aktuellen Empfehlungen für Produktionsqualität)
  • Stellen Sie sicher, dass npm install oder yarn install ohne Warnungen bezüglich Schwachstellen abgeschlossen wird; führen Sie npm audit aus und überprüfen Sie alle gekennzeichneten Probleme, bevor Sie fortfahren
  • Bestätigen Sie, dass Umgebungsvariablen korrekt geladen werden und dass keine Geheimnisse hartcodiert im Projekt sind

Dokumentation und Git-Historie überprüfen:

  • Stellen Sie sicher, dass die README die Einrichtung, Ausführung, Erstellung und das Testen des Projekts klar beschreibt
  • Überprüfen Sie die aktuelle Commit-Historie, um zu verstehen, was wie und warum geändert wurde
  • Prüfen Sie, ob offene Pull-Anfragen gegen den neuesten Haupt-Branch zurückgesetzt wurden, um veralteten oder widersprüchlichen Code zu vermeiden

Tools für statische Analyse einrichten:

  • Bestätigen Sie, dass ESLint eslint-plugin-n verwendet, um Node.js-spezifische Probleme abzudecken. Erzwingen Sie no-process-exit und stellen Sie sicher, dass no-sync streng auf HTTP-Routen angewendet wird, während es für Skriptstarts oder CLI-Tools erlaubt ist
  • Bestätigen Sie, dass Prettier oder ein äquivalenter Formatierer vorhanden und im Projekt konsistent angewendet wird
  • Verifizieren Sie, dass Linting- und Formatierungsprüfungen automatisch in der CI/CD-Pipeline vor jedem Merge ausgeführt werden

Projektstruktur und Codeorganisation

Wenn man sich ein gut organisiertes Node.js-Projekt ansieht, kann man einiges über das Team, das es erstellt hat, erkennen. Wenn Module verstreut sind, Verantwortlichkeiten verschwimmen und Dateien von wem auch immer, der es gerade eilig hatte, benannt werden, kostet jede zukünftige Änderung doppelt so viel, wie sie sollte.

Ordnerstruktur und Modulgrenzen:

  • Verifizieren Sie, dass das Projekt einer konsistenten Struktur folgt, z. B. durch Trennung von Routen, Controllern, Diensten und Datenzugriffsschichten in verschiedene Ordner
  • Bestätigen Sie, dass Geschäftslogik nicht in Routenhandlern lebt; Routenhandler sollten Servicefunktionen delegieren und nicht direkt Abfragen ausführen oder Daten verarbeiten

Schlechte Praxis:

// Routenhandler, der zu viel tut
app.post('/orders', async (req, res) => {
  const order = await db.query('INSERT INTO orders ...', [req.body]);
  await sendEmail(order.userEmail, 'Order confirmed');
  await updateInventory(order.items);
  res.json(order);
});

Gute Praxis:

// Routenhandler delegiert an einen Service
app.post('/orders', async (req, res, next) => {
  try {
    const order = await OrderService.create(req.body);
    res.status(201).json(order);
  } catch (err) {
    next(err);
  }
});

Namenskonventionen und Lesbarkeit:

  • Verwenden Sie camelCase für Variablen und Funktionen, PascalCase für Klassen und UPPER_SNAKE_CASE für Konstanten
  • Vermeiden Sie kurze, kryptische Namen wie fn, tmp oder data. Jeder Funktionsname sollte beschreiben, was er tut, nicht was er ist
  • Stellen Sie sicher, dass Dateien konsistent benannt werden. Das bedeutet, wenn Controller user.controller.js heißen, sollten sie alle diesem Muster folgen und nicht zwei Ordner später zu user-controller.js wechseln

Modulnutzung und CommonJS vs. ESM:

  • Bestätigen Sie, dass das Projekt durchgängig ein Modulsystem verwendet, entweder require/CommonJS oder import/ESM; das Mischen beider ohne Konfiguration ist eine Quelle für subtile Laufzeitfehler
  • Prüfen Sie, ob interne Module mit relativen Pfaden importiert werden und ob keine zirkulären Abhängigkeiten bestehen. Zirkuläre Abhängigkeiten verhalten sich je nach Modulsystem unterschiedlich: in CommonJS ergeben sie zur Laufzeit stillschweigend undefined, während sie in ESM einen fatalen ReferenceError auslösen

Async-Muster und Event-Loop-Gesundheit

Hier unterscheiden sich Node.js-Projekte am schärfsten von Anwendungen in anderen Sprachen. Node.js verarbeitet alles auf einem einzigen Thread über eine Event-Schleife, und laut der offiziellen Node.js-Dokumentation muss jeder JavaScript-Callback schnell abgeschlossen werden. Das Blockieren dieser Schleife, selbst kurzzeitig, lässt jede gleichzeitige Anfrage warten.

Vermeiden Sie Blockaden der Event-Schleife:

  • Achten Sie auf synchrone Dateisystemaufrufe in Hot Paths: fs.readFileSync, fs.writeFileSync und ähnliche Funktionen blockieren die Event-Schleife vollständig, bis die Operation abgeschlossen ist. Ersetzen Sie sie durch ihre asynchronen Äquivalente
  • Prüfen Sie auf große, synchrone Datenverarbeitungsschleifen. Wenn eine Funktion Tausende von Datensätzen in einem einzigen Tick verarbeitet, sollte sie an einen Worker-Thread ausgelagert werden
  • Überprüfen Sie die Verwendung von JSON.parse und JSON.stringify bei sehr großen Payloads, da diese synchron sind und die Schleife blockieren können, wenn die Daten groß genug sind

Schlechte Praxis:

app.get('/config', (req, res) => {
  const config = fs.readFileSync('./config.json', 'utf8'); // blockiert alle Anfragen
  res.json(JSON.parse(config));
});

Gute Praxis (Vermeidung von Blockaden der Event-Schleife):

app.get('/config', async (req, res, next) => {
  try {
    const config = await fs.promises.readFile('./config.json', 'utf8');
    res.json(JSON.parse(config));
  } catch (err) {
    next(err);
  }
});

Async/await und Promise-Handling:

  • Stellen Sie sicher, dass jede asynchrone Funktion eine ordnungsgemäße Fehlerbehandlung hat; eine nicht abgefangene Promise-Ablehnung in Node.js beendet den Prozess in neueren Versionen
  • Prüfen Sie auf unnötige sequentielle await-Aufrufe, bei denen Operationen parallel mit Promise.all ausgeführt werden könnten

Schlechte Praxis:

// Sequenziell — Benutzer und Bestellungen werden nacheinander abgerufen
const user = await fetchUser(id);
const orders = await fetchOrders(id);

Gute Praxis:

// Parallel — beide werden gleichzeitig abgerufen
const [user, orders] = await Promise.all([fetchUser(id), fetchOrders(id)]);
  • Bestätigen Sie, dass .catch()-Handler an alle eigenständigen Promises angehängt sind, die nicht awaitet werden
  • Achten Sie auf asynchrone Funktionen, die innerhalb von forEach-Schleifen aufgerufen werden. Dieses Muster wartet nicht darauf, dass die asynchrone Arbeit abgeschlossen ist, und unterdrückt Fehler stillschweigend. Verwenden Sie stattdessen Promise.all mit .map()

Worker-Threads für CPU-intensive Aufgaben:

  • Identifizieren Sie alle CPU-intensiven Operationen wie Bildverarbeitung, kryptografische Berechnungen oder große Datentransformationen
  • Verifizieren Sie, dass diese Aufgaben an Worker-Threads mit dem integrierten worker_threads-Modul von Node.js ausgelagert werden und nicht den Haupt-Thread blockieren

Fehlerbehandlung

Eine Anwendung, die Fehler elegant behandelt, ist eine Anwendung, der Betreiber vertrauen. Wenn Ihre nicht dieser Anforderung entspricht, ist dies ein Produktionsvorfall, der auf Sie wartet.

Konsistente Fehlerweiterleitung:

  • Verifizieren Sie, dass Fehler mit next(err) an Express-Middleware übergeben und nicht ad hoc innerhalb jedes Routenhandlers behandelt werden. Eine zentralisierte Fehlerbehandlung sorgt für konsistentes Verhalten und protokolliert an einem Ort
  • Stellen Sie sicher, dass benutzerdefinierte Fehlerklassen von der integrierten Error-Objektklasse erben und eine aussagekräftige Nachricht und einen Statuscode enthalten
class AppError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.statusCode = statusCode;
    this.isOperational = true;
  }
}

Unterscheidung zwischen operativen und Programmierfehlern:

  • Operative Fehler sind erwartete Ereignisse: Ein Benutzer sendet ungültige Daten, eine Datenbankverbindung läuft ab, eine Drittanbieter-API gibt eine 503 zurück. Diese sollten abgefangen, protokolliert und mit einer aussagekräftigen Antwort an den Client zurückgegeben werden
  • Programmierfehler sind Bugs: Zugriff auf eine Eigenschaft von undefined, Aufruf einer nicht existierenden Funktion. Diese sollten den Prozess zum Absturz bringen und von einem Prozessmanager wie PM2 oder einer Container-Neustartrichtlinie abgefangen werden
  • Bestätigen Sie, dass der Code keine Programmierfehler stillschweigend in try/catch-Blöcken mit einem leeren catch-Block unterdrückt

Unbeantwortete Ablehnungen und nicht abgefangene Ausnahmen:

  • Verifizieren Sie, dass die Anwendung Handler für process.on(‘unhandledRejection’) und process.on(‘uncaughtException’) registriert, um den Fehler vor dem Beenden zu protokollieren, anstatt ohne Spuren abzustürzen
  • Stellen Sie sicher, dass die Anwendung einen ordnungsgemäßen Shutdown-Prozess versucht (Schließen von Serververbindungen und Datenbankpools), bevor process.exit(1) aufgerufen wird, um in Bearbeitung befindliche Anfragen nicht zu verlieren
process.on('unhandledRejection', (reason) => {
  logger.error('Unhandled rejection:', reason);
  process.exit(1);
});

Sicherheitsbestpraktiken

Die Wahrheit ist, dass Node.js-Sicherheitsprobleme eine reale Bedrohung darstellen. Daher müssen Sie diese von Tag eins der Arbeit am Projekt an planen. Allein im Jahr 2024 wurden in hochrangigen Paketen, darunter web3-utils (CVE-2024-21505) und dset (CVE-2024-21529), Prototype-Pollution-Schwachstellen gefunden, die zur Fernausführung von Code führen könnten. Die Größe des npm-Ökosystems ist seine größte Stärke und eine seiner größten Risikooberflächen.

Schutz vor Prototype Pollution:

  • Achten Sie auf Code, der benutzergenerierte Objekte ohne Validierung zusammenführt oder klont, wie z. B. rekursive Merge-Funktionen und Deep-Clone-Dienstprogramme für nicht vertrauenswürdige Eingaben, die eine häufige Einstiegsstelle für Prototype Pollution sind
  • Stellen Sie sicher, dass Objekte, die Benutzereingaben verarbeiten, wo angemessen mit Object.create(null) erstellt werden, um die Prototypenkette vollständig zu entfernen
  • Verifizieren Sie, dass JSON-Payloads aus externen Quellen vor der Verarbeitung gegen ein Schema validiert werden

Eingabevalidierung und Injectionschutz:

  • Bestätigen Sie, dass alle eingehenden Anfragedaten, Query-Parameter, Header und Body-Felder vor der Verwendung validiert werden. Bibliotheken wie zod, joi oder express-validator sind Standardwerkzeuge dafür
  • Überprüfen Sie alle Datenbankabfragen auf parametrisierte Eingaben, da zeichenkettenbasierte Abfragen ein direkter Weg zu SQL-Injection sind
  • Überprüfen Sie jegliche Verwendung von eval(), new Function() oder child_process.exec() mit dynamischen Eingaben. Diese sollten als kritische Schwachstellen behandelt werden, es sei denn, es gibt eine explizite und gut dokumentierte Begründung

HTTP-Sicherheitsheader und HTTPS:

  • Bestätigen Sie, dass Helmet oder eine äquivalente Middleware vorhanden ist, um sicherheitsrelevante HTTP-Header einzustellen, einschließlich Content-Security-Policy, X-Frame-Options und Strict-Transport-Security
  • Verifizieren Sie, dass die Anwendung HTTPS in der Produktion erzwingt und keine einfachen HTTP-Anfragen für authentifizierte Routen akzeptiert
  • Prüfen Sie, ob Cookie-Einstellungen die Flags Secure, HttpOnly und SameSite enthalten

Ratenbegrenzung und Schutz vor Denial-of-Service:

  • Verifizieren Sie, dass API-Endpunkte, insbesondere Authentifizierungsendpunkte, eine Ratenbegrenzung aufweisen, z. B. mithilfe von Middleware wie express-rate-limit
  • Achten Sie auf reguläre Ausdrücke, die auf Benutzereingaben angewendet werden; ineffiziente Muster können ausgenutzt werden, um CPU-Zeit in einem sogenannten ReDoS-Angriff zu verbrauchen

Geheimnisse und Authentifizierung:

  • Bestätigen Sie, dass JWT-Geheimnisse, API-Schlüssel und Datenbankanmeldeinformationen niemals hartcodiert in Quelldateien vorkommen oder in die Versionskontrolle eingecheckt werden
  • Überprüfen Sie die Token-Validierungslogik und stellen Sie sicher, dass Algorithmusbeschränkungen für JWTs vorhanden sind, um die Schwachstelle des ‘none’-Algorithmus zu verhindern
  • Verifizieren Sie, dass für die Passwortverschlüsselung bcrypt, argon2 oder scrypt verwendet wird, nicht MD5, SHA-1 oder einfaches SHA-256 ohne Salt

Performance-Optimierung

Eine Node.js-Anwendung, die in der Entwicklung schnell läuft, verhält sich unter Produktionslast oft sehr anders. Performance-Probleme verschlimmern sich schnell, wenn viele gleichzeitige Verbindungen bestehen.

Effizienz von Datenbankabfragen:

  • Überprüfen Sie alle Datenbankabfragen auf N+1-Muster. Wenn eine Route eine Abfrage zum Abrufen einer Liste von Datensätzen und dann eine separate Abfrage pro Datensatz zum Abrufen zugehöriger Daten durchführt, wird sie bei Skalierung stark verlangsamt
  • Stellen Sie sicher, dass Indizes für alle Felder vorhanden sind, die in WHERE-Klauseln, JOINs und ORDER BY-Ausdrücken verwendet werden
  • Prüfen Sie auf unbegrenzte Abfragen, da jede Abfrage, die eine beliebige Anzahl von Zeilen ohne Paginierung zurückgeben kann, ein zukünftiges Speicher- und Antwortzeitproblem darstellt

Caching:

  • Identifizieren Sie teure Operationen, wie z. B. komplexe Datenbankabfragen oder externe API-Aufrufe, die von Caching profitieren könnten
  • Verifizieren Sie, dass eine Caching-Schicht, wie z. B. Redis oder ein In-Memory-Cache, für häufig abgerufene, sich langsam ändernde Daten vorhanden ist
  • Prüfen Sie, ob eine Logik zur Cache-Invalidierung vorhanden ist, denn ein Cache, der unbegrenzt wächst oder veraltete Daten liefert, ist schlechter als gar kein Cache

Verbindungspooling und Ressourcenmanagement:

  • Bestätigen Sie, dass Datenbankverbindungen einen Pool verwenden und nicht pro Anfrage eine neue Verbindung öffnen. Dies ist ein häufiger Fehler, der dazu führt, dass Node.js-Anwendungen unter Last die Verbindungslimits der Datenbank erschöpfen
  • Prüfen Sie, ob HTTP-Clients und externe Serviceverbindungen wiederverwendet und nicht pro Anfrage erstellt werden

Streaming für große Datenmengen:

  • Überprüfen Sie Endpunkte, die große Dateien oder Datenbankergebnisdatensätze in den Speicher lesen, bevor sie an den Client gesendet werden. Diese sollten Node.js-Streams verwenden, um Daten inkrementell zu leiten, anstatt alles zuerst zu puffern

Abhängigkeitsmanagement

Es gibt über 2 Millionen Pakete im npm-Registry. Durch diese trägt jedes Node.js-Projekt einen Abhängigkeitsbaum, der weit über das hinausgeht, was ein Team direkt kontrolliert. Daher ist der Baum selbst eine Risikooberfläche, die Sie effektiv verwalten müssen.

Abhängigkeiten aktuell und minimal halten:

  • Führen Sie npm audit aus und verifizieren Sie, dass alle hochgradigen und kritischen Schwachstellen behoben wurden oder eine ausdrückliche, dokumentierte Ausnahme vorliegt
  • Überprüfen Sie package.json auf nicht mehr verwendete Abhängigkeiten, da ungenutzte Pakete die Installationszeit und die Angriffsfläche erhöhen, ohne einen Mehrwert zu bieten
  • Prüfen Sie, ob die Versionsbereiche in package.json nicht zu permissiv sind. Während Semantic Versioning vorschreibt, dass kleinere Updates abwärtskompatibel sein müssen, kann ein Caret-Bereich wie ^4.0.0 tatsächlich Breaking Changes einführen, wenn Paketautoren den Standard verletzen; package-lock.json oder yarn.lock sollten committet werden, um reproduzierbare Installationen zu gewährleisten

Bewertung von Drittanbieterpaketen:

  • Prüfen Sie bei jeder neu hinzugefügten Abhängigkeit das npm-Downloadvolumen, das Datum der letzten Veröffentlichung und die Anzahl der offenen Sicherheitswarnungen
  • Bevorzugen Sie Pakete, die aktiv gewartet werden und eine klare Besitzhistorie aufweisen, da ein vor vier Jahren veröffentlichtes Paket ohne Aktivität ein Risiko für die Lieferkette darstellt
  • Verifizieren Sie, dass keine schweren Utility-Bibliotheken nur für eine Funktion importiert werden; lodash, das komplett importiert wird, fügt Kilobytes hinzu, wo eine einzelne native Methode die gleiche Aufgabe erfüllt

Tests und Codeabdeckung

Tests sind keine Bürokratie, sondern der Mechanismus, mit dem ein Team kommuniziert, was der Code tun soll, und der einzige zuverlässige Weg zu wissen, ob eine Änderung etwas kaputt gemacht hat.

Abdeckung von Unit- und Integrationstests:

  • Verifizieren Sie, dass alle Servicefunktionen und Utility-Module Unit-Tests haben, die den Happy Path, Edge Cases und Fehlerbedingungen abdecken
  • Bestätigen Sie, dass Routenhandler Integrationstests haben, die den vollständigen Request-Response-Zyklus validieren, einschließlich der Authentifizierungs-Middleware
  • Prüfen Sie, ob die Testsuite ohne Netzwerk- oder Datenbankaufrufe ausgeführt wird, es sei denn, diese Aufrufe sind absichtliche Integrationstests, da Unit-Tests Mocks für externe Abhängigkeiten verwenden sollten

Testqualität, nicht nur Abdeckungszahlen:

  • Überprüfen Sie, ob Tests sinnvolle Ergebnisse prüfen und nicht nur verifizieren, dass eine Funktion aufgerufen wurde; ein Test, der nur toHaveBeenCalled prüft, ohne das Ergebnis zu validieren, schützt das Verhalten nicht
  • Stellen Sie sicher, dass Testnamen das getestete Verhalten beschreiben, z. B. it(‘returns 401 when the token is expired’) anstatt it(‘handles auth’)
  • Bestätigen Sie, dass die CI-Pipeline bei Testfehlern fehlschlägt und dass keine Tests mit it.skip oder xit ohne dokumentierten Grund übersprungen werden

Umgebungskonfiguration und Geheimnisse

Wenn Sie den Unterschied zwischen dem Verhalten einer Node.js-Anwendung in der Entwicklung und in der Produktion sehen, dann schauen Sie sich Probleme an, die aus der Konfiguration stammen.

Management von Umgebungsvariablen:

  • Bestätigen Sie, dass alle umgebungsspezifischen Konfigurationen, einschließlich Datenbank-URLs, API-Schlüsseln, Feature-Flags und Portnummern, aus Umgebungsvariablen stammen und nicht aus hartcodierten Werten
  • Verifizieren Sie, dass eine .env.example-Datei im Repository vorhanden ist, die alle erforderlichen Variablen ohne ihre tatsächlichen Werte dokumentiert. Die eigentliche .env-Datei muss in .gitignore enthalten sein
  • Prüfen Sie, ob die Anwendung beim Start lautstark fehlschlägt, wenn erforderliche Umgebungsvariablen fehlen, anstatt in einem teilweise konfigurierten Zustand zu laufen, der später zu subtilen Fehlern führt
// Erforderliche Umgebungsvariablen beim Start validieren
const required = ['DATABASE_URL', 'JWT_SECRET', 'PORT'];
for (const key of required) {
  if (!process.env[key]) {
    throw new Error(`Fehlende erforderliche Umgebungsvariable: ${key}`);
  }
}

Produktions- vs. Entwicklungskonfiguration:

  • Verifizieren Sie, dass NODE_ENV in allen Bereitstellungsumgebungen korrekt gesetzt ist und dass die Anwendung in jeder Umgebung entsprechend funktioniert, z. B. nur ausführliche Fehlermeldungen in der Entwicklung
  • Bestätigen Sie, dass Debugging-Tools und ausführliches Logging in Produktions-Builds deaktiviert sind

Protokollierung und Beobachtbarkeit

Stellen Sie sich vor, Sie erhalten um 2 Uhr morgens eine Benachrichtigung, dass etwas schiefgelaufen ist. Der Unterschied zwischen einer 15-minütigen Behebung dieses Problems und einer stundenlangen Untersuchung wird von der Qualität Ihrer Protokolle abhängen.

Strukturierte Protokollierung:

  • Verifizieren Sie, dass die Anwendung eine strukturierte Protokollierungsbibliothek wie pino oder winston verwendet und nicht scattered console.log-Anweisungen im gesamten Codebase. Strukturierte Protokolle sind durchsuchbar und kompatibel mit Log-Aggregations-Tools
  • Stellen Sie sicher, dass Protokolleinträge einen Zeitstempel, eine Protokollebene, eine Request-ID und genügend Kontext enthalten, um zu verstehen, was passiert ist, ohne raten zu müssen

Aussagekräftige Protokollebenen:

  • Bestätigen Sie, dass die Protokollebenen korrekt verwendet werden: info für normale Operationen, warn für unerwartete, aber nicht kritische Bedingungen, error für Fehler, die Aufmerksamkeit erfordern, und debug für detaillierte Diagnosedaten, die niemals in der Produktion erscheinen sollten
  • Achten Sie auf console.log-Aufrufe im Produktionscode. Dies ist ein Zeichen dafür, dass die Protokollierung nicht ordnungsgemäß eingerichtet wurde und wichtige Informationen möglicherweise an die falsche Stelle gelangen

Request-Tracing und Health Checks:

  • Verifizieren Sie, dass die Anwendung jeder eingehenden Anfrage eine eindeutige Request-ID zuweist und diese in allen Protokolleinträgen für diese Anfrage weitergibt. Dadurch wird es möglich, die Anfrage eines einzelnen Benutzers über ein verteiltes System zu verfolgen
  • Bestätigen Sie, dass ein Health-Check-Endpunkt existiert und eine aussagekräftige Antwort zurückgibt, die angibt, ob die Anwendung und ihre Abhängigkeiten betriebsbereit sind

Node.js Code-Überprüfung mit Redwerk

Diese Checkliste selbst durchzugehen ist ein guter Anfang, aber der nächste Schritt ist, ein externes Team sie für Sie durchlaufen zu lassen. Bei Redwerk bauen und überprüfen wir Anwendungen seit über zwei Jahrzehnten. Unser Team deckt das gesamte Spektrum ab: Architektur, Asynchronitätsmuster, Sicherheit, Leistung und Tests. Wir identifizieren Probleme, erklären, warum sie wichtig sind, und geben Ihnen einen klaren Weg zur Behebung.

Werfen wir einen Blick darauf, wie dies in der Praxis aussieht, anhand unserer Fallstudie für Kooky, einem intelligenten wiederverwendbaren Bechersystem, das wir von Grund auf neu entwickelt haben. Es ist eine Plattform für den Schweizer Markt, die auf einem ereignisgesteuerten Echtzeit-Backend läuft. Derzeit werden QR-basierte Becherverfolgung, Live-Kontoaktualisierungen und sofortige Einzahlungsabwicklung abgewickelt. Sie operiert in Partnerschaft mit den Schweizerischen Bundesbahnen, Valora und Coop.

Um dieses System unter gleichzeitiger Last stabil zu halten, mussten wir jeden Punkt dieser Checkliste vom ersten Tag an richtig machen, einschließlich:

  • Async-Muster, die die Event-Schleife nie aushungern
  • Ratenbegrenzung an Zahlungsendpunkten
  • Strukturierte Protokollierung, die Produktionsvorfälle nachverfolgbar macht
  • Abhängigkeitsbaum, der bei jeder Veröffentlichung geprüft wird

Mit all dem wurde Kooky zu der führenden grünen Tech-Startup der Schweiz, und eine gute Architektur hatte viel damit zu tun.

Über 50 Unternehmen haben uns vertraut, ihre Produkte von Grund auf neu zu entwickeln oder zu prüfen. Und egal, ob Ihr Node.js-Projekt eine Startup-API oder eine Enterprise-Plattform ist, unsere Node.js-Entwicklungserfahrung bedeutet, dass wir genau wissen, wo die Probleme versteckt sind.

Wenn Ihre Codebasis eine genauere Betrachtung verdient, kontaktieren Sie uns, und wir kümmern uns darum.

Sehen Sie, welchen Unterschied eine Code-Überprüfung machen kann: Wie wir über 80 Verbesserungen und Sicherheitsrisiken für einen mobilen Marktplatz identifiziert haben

Bitte geben Sie Ihre Geschäfts-E-Mail-Adresse ein ist keine Geschäfts-E-Mail