Blog

Besseren Code mit Linting-, Formatierungs- und Analysetools schreiben

SEP 29, 2020

Menschen machen manchmal Fehler, die selbst Code Reviews nicht zuverlässig aufdecken können. Deshalb ist es sehr empfehlenswert, Linting-, Formatierungs- und Analysetools kombiniert einzusetzen, um solche Probleme im Code vor einem Deployment zu erkennen.

Olli Rautiainen

Code Reviews eignen sich hervorragend, um schlechtes Design aufzudecken und Wissen auf höherer Ebene zu teilen. Fehler können dabei jedoch manchmal unbemerkt bleiben. In diesem Blogbeitrag zeigen wir, wie ihr Linting-, Formatierungs- und Analysetools kombiniert, um Probleme im Code zu erkennen, die bei einem Review möglicherweise nicht auffallen.

Programmiersprachen und Design Patterns entwickeln sich ständig weiter. Daher sollten auch diese Tools und ihre Konfigurationen aktiv gepflegt werden, um bestmögliche Funktionalität, Lesbarkeit und aktuelle Syntax sicherzustellen. Entwickler sollten zudem keine Scheu davor haben, Code bei Updates und Fehlerbehebungen zu refaktorieren – selbst wenn er bereits korrekt funktioniert –, wenn sie einen besseren Weg zum gewünschten Ergebnis finden. Wenn diese Linting-, Formatierungs- und Analysetools jedoch von Beginn der Entwicklung an möglichst früh sinnvoll eingesetzt werden, sind im Wartungsmodus deutlich weniger Refaktorierungen nötig. Das kann auf allen Seiten viel Zeit und wertvolle Ressourcen sparen.

Wir stellen drei verschiedene Arten hilfreicher Tools für euren Code vor, zeigen, was ihr mit ihnen erreichen könnt, und helfen euch dabei, sie sofort in der Entwicklung einzusetzen. Zunächst definieren wir jedoch, was im Kontext dieses Blogbeitrags guter, wartbarer Code ist.

  1. Guter Code tut, was er soll

Zuallererst muss Code funktionieren. Wenn der Code Fehler enthält, ist alles andere nahezu wertlos. Die Tools sollten daher dabei helfen, potenzielle Fehler zu beseitigen.

  1. Guter Code ist leicht zu lesen und zu ändern

Wenn Code für Menschen schwer verständlich ist, wird das Lesen zur Qual und Änderungen führen wahrscheinlich zu Fehlern. Die Tools sollten daher Einfachheit und Klarheit erhöhen.

  1. Guter Code folgt gängigen Best Practices

Es gibt in der Regel viele Möglichkeiten, eine bestimmte Logik zu implementieren, von denen einige scheinbar gleich gut sind. Bei unseren Entscheidungen sollten wir jedoch eine klare Haltung einnehmen, um Konsistenz nicht nur innerhalb einer Codebasis, sondern projektübergreifend zu fördern. Schließlich verbessert Vertrautheit die Lesbarkeit. Die Tools sollten daher die Konsistenz erhöhen und vor schlechten Praktiken warnen.

Tools für besseren Code

  • Linter

Linter

  • Linter wie ESLint und Pylint werden hauptsächlich eingesetzt, um logische Probleme im Code aufzuspüren. Sie sind besonders wichtig bei interpretierten und schwach typisierten Sprachen wie JavaScript und Python, da diesen der zusätzliche Kompilierungsschritt fehlt, der auftretende Fehler erkennen könnte. Insbesondere JavaScript ist eine sehr dynamische und eigenwillige Sprache, die zu seltsamem unbeabsichtigtem Verhalten führen kann, wenn Best Practices nicht befolgt werden. Beispielsweise solltet ihr === und !== statt == und != verwenden, da die Typumwandlung in JavaScript gelinde gesagt sehr unintuitiv ist. Glücklicherweise gibt es dafür und für andere ähnliche gängige Praktiken eine ESLint-Regel.

  • ESLint lässt sich zudem sehr flexibel erweitern und kann so verwendet und konfiguriert werden, dass es vor nahezu allem warnt. Um das Standard-Regelwerk zu erweitern, solltet ihr wahrscheinlich Plugins für alle spezifischen Frameworks, möglicherweise sogar einige Libraries sowie für Barrierefreiheit verwenden, etwa eslint-plugin-jsx-a11y. Da jedes Projekt anders ist, sollten die Regeln an die Versionsverwaltung des Projekts angepasst werden. Je näher die Konfigurationen jedoch an den empfohlenen Standardeinstellungen liegen, desto einfacher ist es, Best Practices zu pflegen und einzuhalten. Ein guter Einstieg besteht darin, stets die neuesten Versionen aller Packages und die empfohlenen Regelwerke jedes einzelnen zu verwenden (siehe Beispielkonfiguration). Passt eine Regel nicht zum Projekt, könnt ihr sie einfach deaktivieren, indem ihr sie auf „off“ setzt.

  • Linter sind am hilfreichsten, wenn sie in den Editor integriert sind und den Code während des Tippens prüfen, damit ihr möglichst schnell Feedback bekommt. Mögliche Fehler werden dann immer hervorgehoben und lassen sich schnell beheben. Nehmen wir zum Beispiel an, ich arbeite an einer React-App und implementiere ein neues Formular. Ohne ESLint und eslint-plugin-jsx-a11y ist es wahrscheinlich, dass das Formular schwer per Tastatur zu bedienen oder mit Screenreadern nicht vollständig verständlich ist – ohne dass es jemand bemerkt, bis dadurch echter Schaden entstanden ist. Mit einem gut konfigurierten Linter und Editor erhalte ich hingegen sofort Warnungen, wenn ein interaktives Element keine Tastaturereignisse hat oder Bilder keine nicht redundanten Alt-Attribute besitzen.

  • Linter können auch als Style Guides für die Formatierung eingesetzt werden, wie bei der beliebten eslint-config-airbnb. Meiner Meinung nach ist es jedoch besser, einen guten Stil mit automatischen Formatierern durchzusetzen und den Linter ausschließlich auf logische Probleme zu konzentrieren.

  • Formatierer

  • Formatierer wie Prettier und Black sorgen für einen einheitlichen Stil im Projekt, indem sie den Code gemäß ihrem Regelwerk ausgeben. Formatierer werden zusätzlich zu Lintern eingesetzt: Linter dienen der Codequalität, Formatierer den Formatierungsregeln. Neben JavaScript und TypeScript kann Prettier unter anderem auch CSS, Less, SCSS, HTML, JSON, Markdown und YAML formatieren. Da die Formatierung des Codes seine Funktionsweise nicht wirklich beeinflusst, ist weniger wichtig, wie genau das Regelwerk aussieht, sondern dass überhaupt gemeinsame Regeln verwendet werden. Deshalb sind die besten Formatierer meinungsstark und benötigen gar keine Konfiguration. Zwar lassen sich die meisten Formatierungsregeln diskutieren, doch ihre Standardeinstellungen sind auf Lesbarkeit optimiert, und es gibt selten einen logischen Grund, davon abzuweichen. Für maximale Effizienz empfiehlt sich wahrscheinlich ein Formatierungsschritt im Pre-Commit-Hook, damit schlecht formatierter Code nicht committed werden kann. So können Entwickler den Code in dem Format schreiben, das für sie am angenehmsten ist. Zusätzlich können Formatierer in den Editor integriert werden, um Code beim Speichern einer Datei zu formatieren. Die Vorteile sind enorm: viel Zeitersparnis, weil keine Entscheidungen mehr zum Stil nötig sind und Leerzeichen oder andere optionale Zeichen nicht mehr manuell eingegeben werden müssen. Selbst umfangreiche Codebasen lassen sich in wenigen Sekunden formatieren. Formatierer erleichtern auch den Einstieg in die Arbeit an einer Codebasis erheblich, da ihr die Formatierungskonventionen des Projekts nicht mehr lernen müsst.

  • Statische Codeanalyse

  • Tools zur statischen Codeanalyse wie SonarQube analysieren eure Codebasis und liefern entsprechende Metriken. SonarQube unterstützt hervorragend 27 verschiedene Sprachen, darunter auch CSS und HTML. Durch die Untersuchung aller möglichen Ausführungspfade erkennt es Bugs, die schwer zu finden sind und anderen Tools oder Menschen möglicherweise entgehen. Es warnt vor Code Smells, die die Wartung erschweren, obwohl der Code wie vorgesehen funktioniert – zum Beispiel dupliziertem, zu komplexem oder nicht abgedecktem Code. Außerdem warnt es vor Sicherheitslücken und potenziell unsicherem Code und bewertet die Zuverlässigkeit, Sicherheit, Wartbarkeit, Abdeckung und Duplizierungen der gesamten Codebasis sowie des neu hinzukommenden Codes. SonarQube wird am besten als Teil der CI/CD-Pipeline eingesetzt, um den Code bei jeder Änderung zu scannen, die in einen überwachten Branch gepusht wird. Zusätzlich gibt es die SonarLint-Erweiterung für Editoren, die ergänzend zu SonarQube verwendet werden kann und bereits beim Schreiben von Code vor Fehlern warnt. 

Fazit

Alle genannten Tools lassen sich schnell und einfach einführen. Sie unterstützen und fördern Best Practices und bieten ein hervorragendes Preis-Leistungs-Verhältnis, da sie den Zeit- und Kostenaufwand für das Schreiben guten Codes reduzieren. Am effektivsten kombiniert ihr sie so: Linting während des Schreibens, Formatierung über einen Pre-Commit-Hook und SonarQube in der CI/CD-Pipeline. Sie übernehmen automatische Code Reviews für Änderungen, was bei Aufgaben zur Softwarewartung oft ausreicht. Alle Tools können jederzeit im Lebenszyklus einer Software eingeführt werden. Besser, effektiver und einfacher ist es jedoch, sie von Anfang an zu nutzen. Zusammen mit guten Technologieentscheidungen, einem durchdachten Design und regelmäßigen Updates sorgen sie dafür, dass die Codebasis heute und in Zukunft möglichst einfach wartbar bleibt.

  • Softwareentwicklung
  • Anwendungsmanagement

Subscribe to our newsletter