dogfood

Tag: WebDev

Ich konnte meinen ältesten (längsten?) Kunden endlich davon überzeugen, das erste Mal seit 20 Jahren(!) das Markup seiner Website von mir überarbeiten zu lassen.

… und ich habe bei der Validierung erfahren, dass das border-Attribut an Bildern inzwischen deprecated ist.

Ältere Menschen unter uns, wissen noch, was früher passierte, wenn man Border an verlinkten Bildern nicht auf null setzte… Sooooo alt bin ich.

Am Wochenende im inzwischen dritten Anlauf gescheitert, „Full Site Editing“, „Block Themes“ und „Gutenberg“ von WordPress zu verstehen.

Die Dokus sind IMHO unzureichend. Der Genickbruch ist die fehlende „separation of concerns“. Was ist für was verantwortlich? Was sind Daten die über das Template ausgespielt werden, was sind Daten aus dem Konfigurations-JSON und was wird über den Block-Editor in die Datenbank abgespeichert. Es gibt keine klare Trennung und ich habe das Gefühl, dass es mehrere Wege gibt um Dinge zu erreichen. Die fehlende, klare Trennung führt aber bei der Entwicklung zu Seiteneffekten.

Ich habe keine Debug-Möglichkeiten gefunden, um dem auf die Spur zu kommen. Bestimmte Einstellungsmöglichkeiten habe ich nur irgendwo tief nur über den Block-Editor gefunden (beispielsweise die IDs der zusammengebauten Menüs) und werden von der Entwicklungsumgebung gegenüber PROD abweichen.

Am Sonntag habe ich dann die Reißleine gezogen und im Projekt angefangen auf Processwire umzuschwenken. Dessen flexiblere Redaktionsoberfläche eignet sich für das Projekt besser, als das Block-Editor-lose, normale WordPress.

Auf Smashing Magazine ist ein laaaaanger Artikel zum Design (oder besser: Konzeption) von Komponenten auf Websites erschienen:

„The Key To Good Component Design Is Selfishness“, Daniel Yuschick, 20.1.2023

Um es vorweg zunehmen: ich schließe mich Yuschicks Schlussfolgerung nicht an und bin da ganz bei einem Leserkommentar unter dem Artikel. Aber das Durchdeklinieren der Probleme und die daraus resultierenden Folgerungen sind anregendes Denkfutter.

Yuschick stellt prototypisch dar, was in jedem größeren Projekt passiert und was in jedem Projekt ein PITA ist: das Aufblähen von Komponenten. Dazu nimmt Yuschick zuerst einen Button (später ein Modal) in einer Grundkonfiguration, als Primary und Secondary Button mit konfigurierbaren Text, und bastelt daraus eine React-Komponente inkl. Markup.

Dann kommt die erste Eskalation: das Projekt will gerne optional ein Icon rechts vom Text haben. Okay, Komponente umgebaut.

  • Nächste Iteration: es soll ein Tertiary Button eingeführt werden und Icons sollen optional links vom Text erscheinen können.
  • Dritte Iteration: Einbau von Icons mit einer Farbe die von der Textfarbe abweicht.
  • Vierte Iteration: Icons-only-Button, also Buttons wo der Text optional ist und die Icon-Position deswegen nicht „links“ oder „rechts“ vom Text sein kann.

Jeder Entwickler kennt dies: jede Iteration kann die grundsätzliche Ausgangssituation derart verändern, dass es nicht mehr über ein Anflanschen zusätzlicher Anforderungen getan ist, sondern ein Komplettumbau eigentlich angemessen wäre. Ein Komplettumbau bringt i.d.R. auch eine Veränderung der Konfiguration mit sich und jede Konfiguration von bereits verbauten Buttons, muss angepasst werden.

Verschiebung of Concerns

Yuschick leitet daraus die Frage nach der „Verantwortung“ einer Komponente ab.

What is the responsibility of an HTML button element exactly? Narrowing down this answer will shine light onto the issues facing the previous Button component.

The responsibilities of the native HTML button element go no further than:

  • Display, without opinion, whatever content is passed into it.
  • Handle native functionality and attributes such as onClick and disabled.

[…]

The onus of formatting any content within the button isn’t the responsibility of the button but of the content itself. The button shouldn’t care. The button should not share the responsibility for its content.

Yuschicks Beobachtung mündet in Fatalismus…

When the component is responsible for the content it displays, it will break down because the content will forever and always change.

… und der Schlussfolgerung: lass Content Content sein und kümmere dich nicht um ihn. In der Verantwortung einer Komponente läge nur das Aussehen (huh?), die Funktionalität (Klicks etc…) und Zustand (Position, Sichtbarkeit).

Würde Yuschicks Artikel an dieser Stelle aufhören, würde ich die Conclusio in Bausch & Bogen verdammen. Aber Yuschick geht noch einen Schritt weiter, mit dem er sein eben verkündetes Dogma dezent aufbricht. Er fängt an, über Komposition, also Zusammenbau von Komponenten zu schreiben. Ein Modal besteht z.B. nicht einfach aus „Inhalt“, sondern Subkomponenten für Header, Main und Footer. Smells like Atomic Design?

Yuschick fängt hier an argumentativ zu wackeln. Während er im Kontext der Komposition von „child components“ spricht, stellt er später die Bestandteile von Modals als „little more than a semantic container for any content“ vor und redet sie wieder klein. Die Frage ob Eingabefelder im Main-Bereich des Modals jetzt „Content“ oder Subkomponenten sind, betrachtet er leider nicht.

Verschiebung of Verantwortung

Der Leserkommentar von Rich arbeitet sich an der nicht möglichen Kapselung von Content entlang der von Yuschick vorgeschlagenen Grenze ab.

Der Schlüssel liegt in Richs Formulierung von „By removing responsibility for content” – die Verantwortung wird aus dem eigenen Verantwortungsbereich weg geschoben … aber wohin sie geschoben wird, wird von Yuschick nicht erwähnt.

Die Grenze von Yuschick bedeutet letztendlich, dass Content HTML-Markup wird (was jetzt schon zB bei Richtext der Fall ist). Und das kann eine sehr problematische Entscheidung sein.

Im Kontext von größeren Websites mit Content Management Systemen ist davon auszugehen, dass Inhalte von Redakteuren gepflegt werden. Diese Redakteure besitzen über ein sehr heterogenes Wissen von HTML. Redaktionsleitfaden mit den Beschreibungen für die Einstellungen von mehreren Dutzend unterschiedlichen Modulen werden eh schnell sehr umfangreich. Darin auch noch die Usance zum Pflegen von HTML-Markup unterzubringen, ist in den Projekten in denen ich drin bin, nicht vermittelbar. Kurz gesagt: Redakteure sind i.d.R. keine HTML-Kenner.

In Yuschicks Definition ist Content nicht mehr Content, sondern ein Brei aus Code und Content – Text mit HTML-Code angereichert, der zufällig auch noch die richtige Klasse am SPAN-Element hat, um im Button das richtige Icon anzuzeigen.

Yuschicks Folgerung löst kein Problem, sondern verschiebt das Problem in eine sehr, sehr üblen Ecke: weg vom Code, Dateien und Templates, hin zu Content, der in Datenbanken versenkt ist. Der ist damit etliche Ecken vom Entwickler weiter weg und wird bei der nächsten Content-Migration einen Haufen Ärger machen.

Fazit

Yuschicks Artikel ist der Tritt in den Hintern, sich noch einmal zu hinterfragen, wie es mit „Separation of Concerns“ im Bereich der Komponenten aussieht. Wieviel Verantwortung hat die Komponente, wieviel Verantwortung haben Subkomponenten und wieviel Verantwortung hat der Inhalt.

Der Verantwortungsbereich des Inhaltes lässt sich daraus ableiten, wer den Inhalt pflegt. In größeren Projekten werden es nicht Entwickler:innen, sondern Redakteure sein und dass reduziert automatisch den Verantwortungsbereich von „Inhalt“.

Was in den Diskussionen über Komponenten IMHO überraschend häufig ausgeblendet wird, sind Hierarchien. Auch in Designsystemen oder Komponentenbaukästen gibt es häufig nur eine einzige Ebene von Komponenten, die einen Button auf Augenhöhe mit einem Modal behandelt.

Ich halte es für eine Stärke von Atomic Design über „Atome“, „Moleküle“ und „Organismen“ den Komponenten eine Hierarchie mitzugeben. Damit ergibt sich auch eine Beschreibung der Verantwortungsbereiche z.B. einer Modal-Komponente und einer Button-Komponente, die in einem Modal steckt. Ein Button ist ein Button ist ein Button ist ein Button. Und für alles was im Modal bzgl. des Buttons darüber hinaus geht, ist das Modal zuständig (abweichende Positionierung etc…). Entweder bin ich an diesem Punkt ein störrischer alter Esel, oder es hat seine Grund, warum die Projekte damit gut laufen.

Im Blog habe ich in den letzten Jahren einige OPs erwähnt. Die OPs waren Teil einer grundsätzlichen Geschichte die ich fixen wollte (und wie sich später herausstellte: musste). Das habe ich im Sommer 2020 losgetreten und in der abgelaufenen Woche begann die letzte Phase, mit einem Abschluss voraussichtlich im Herbst des Jahres. Ich wurde letzte Woche zunehmend nervös, aber die letzte Phase ist besser gelaufen, als ich es erwartet hatte – auch wenn noch viel Arbeit bevorsteht. Als Nachklapp der letzten OP wird aufgrund einer kleinen Komplikation auch noch mal eine kleine Extraschleife gedreht werden müssen.

Things I did.

Nach dem Dauerfrost und Dauerregen, den es seit gefühlt letzten November gab, betrat ich unter der Woche erstmals wieder den Garten. In der ersten Runde musste ich erst mal den ganzen Crap aufsammeln, der von der Straße rein geweht wurde, inklusive Böllerüberreste von Silvester.

Alles sah ätzend aus. Der Rasen war entweder vermoost oder durch die (zu vielen) Pflanztöpfe vom letzten Jahr übersät mit kahlen Stellen. Einmal mehr, habe ich keinen Plan zur Strukturierung des Gartens und Vordergarten. Bah.

Erst einmal die Hasel und den Feldahorn gestutzt und das Schnittgut auf den Totholzhaufen geschmissen.

Things I worked on.

Im Projekt A ist die Frontend-Entwicklungsarbeit größtenteils zum Erliegen gekommen. Das Designsystem wurde bei der Umstellung von Sketch auf Figma gegen die Wand gefahren (Pro-Tipp: man stellt kein Layoutraster ohne Rücksprache um). Seit drei Wochen sind Rettungsversuche im Gang.

Projekt B ist mit der Aufteilung der Entwicklungsarbeit in zwei Teilteams beschäftigt. Dabei ist das Wahren der teamübergreifenden Kohärenz ein ziemlicher Schmerzpunkt. An etlichen Punkten prallt hier unterschiedliches Verständnis aufeinander – von Kundenseite über Teamleiter bis runter zu den Entwicklern.

Nicht direkt mit der Projektarbeit, hat aber ein derzeit großes Thema rund um die Webentwicklung zu tun: die aufkeimende „Anti-Framework“-Diskussion, die sich zum zehnjährigen Jubiläum von React entzündet. Ich mache keinen Hehl daraus, dass ich kein großer Freund von React und seinem großen Zusammenpanschen von Markup, Styling und Javascript oder seinem wechselnden Scope (von „eigentlich machen wir nur DOM-Diffs“ über „Wir können alles“ bis hin zu „Server-Side-Rendering wär’ eigentlich scho’ besser“) bin.

Oxford Harrison hat in einem Pamphlet eine Haltung veröffentlicht, mit der ich mich identifizieren kann: Rethinking the Modern Web.

Da wo es „projekt-relevant“ wird, ist für mich die Frage, ob sich hier ein Generationskonflikt wiederspiegelt, zwischen älteren Entwickler:innen („moi“), die mit Web Standards, Separation of Concerns, Kompatibilität und Einfachheit groß geworden sind, und den „Kiddos“, die Frameworks bereits mit der Muttermilch aufgesogen haben und für die Natives keine Qualität ist.

Mir fällt am Verhalten der „Kiddos“ Dinge auf, die mich ratlos hinterlassen. Eine stete Unruhe, fast so, als wäre die Beschäftigung mit nur einem Problem über längerer Zeit so langweilig, dass man sich mit dem ersten „jo, läuft“ zufrieden stellt und zum nächsten Problem rennt – ungeachtet, ob die erste Lösung qualitativ zufriedenstellend ist.

Es scheint, als würde man jede Problemlösung auf den Zustand „gelöst“ und „nicht gelöst“ herunter brechen, ungeachtet der weiteren Bewertungsvektoren, wie: Resilienz, Einfachheit, Wartbarkeit, Performanz, Integration im Gesamtprojekt.

Rennen wir in eine Generation rein, die eine Aufmerksamkeits-/Konzentrationsspanne von einem TikTok hat?

Dies macht mir nicht nur grundsätzlich Sorgen, sondern auch der Umstand, dass viele der „Kiddos“ sich an diesen Punkten nicht zu bewegen scheinen – und damit bei mir die Frage hinterlassen: was mache ich falsch, was muss ich ändern? I don’t know.

Jo, alles furchtbar pauschalisierend, I know, I know…

Things I read.

Die Trisolaris-Trilogie durchgelesen (okay, bis auf die letzten 50 Seiten) und es war unterm Strich enttäuschend. Siehe meine Rezension.

Was am Ende von den 1.500 Seiten für mich übrig bleibt, ist das Konzept des „Dunklen Walds“. Und ich bin eigentlich erst nach Schreibens meiner Rezension darauf gekommen, wie sehr dieses Konzept eigentlich den ersten Runden der Spiele aus der „Civilization“-Reihe entspricht (und perfekt-getimet kommt Stream daher und will mir Civ VI für sechs Euro hinterher schmeißen).

Ich frage mich, was ich in der Trilogie nicht gesehen habe, dass so ein massiver Hype darum entstanden ist. Was aber nicht als Referenz dienen kann, sind die Verfilmungen, die jetzt auf den Markt kommen. Die Trailer kondensieren den Stoff so immens, dass daraus wirklich etwas Ansprechendes wird. Das ist in der Buchvorlage einfach nicht gegeben gewesen. Was nicht ausschließt, dass die Bücher einen interessanten Rohstoff für eine Verfilmung hergeben – ähnlich wie Asimovs Foundation-Serie.

Things I watched.

Kommissar Wallander – Die Kenneth Branagh-Variante. Ich habe die englische Umsetzung bislang nicht angefasst, weil für mich der Wallander auf ewig mit Rolf Lassgård verbunden ist. Kenneth Branagh klingt dagegen für mich nach Star und einer der mit seinem Image die Figur überstrahlt…

Hoooh boy, wurde ich eines Besseren belehrt. Eine Folge hat gereicht, damit ich nicht mehr den Branagh in Wallander sehe, sondern den Wallander in Branagh. Lassgård mag ich zwar immer noch mehr, aber ich verneige mich wie Branagh mit dieser Rolle umgeht. („Kommissar Wallander“ – derzeit als ARD-Produktion bei Amazon Prime)

The Late Late Night Show with Craig Ferguson – Warum auch immer, ich habe auf YouTube mal wieder Craig Ferguson angesteuert und bin nach zwei Folgen wieder süchtig geworden.

Ferguson ist der Anarchist unter den Late Night Shows gewesen. Es spricht für Ferguson, dass es schwer fällt, zu sagen, was gescriptet und was Impro war (Beispiel).

Things I played.

Mitte der Woche wurde die (der?) Early Access von „The Last Starship“ freigeschaltet, dem neuesten Spiel von „Introversion Software“, den Machern u.a. von„Prison Architect“.

Die grundsätzliche Spielidee, das Aufbauen eines Raumschiffes, ist klar umrissen. Nicht ganz so klar, ist der „Flavour“, mit dem man sich von „Star Haven“ oder „Stardeus“ absetzen will. Die Rede ist von Spurenelementen von „FTL“, „Elite“ und „Factorio“.

Diese Spurenelemente lassen sich erkennen. Aber ich bin enttäuscht über den aktuellen Stand – gemessen am Status, der im letzten Juni den Medien gezeigt wurde. Es hat sich nicht viel getan. Es gibt recht wenig Erklärungen und Hilfe. Auch die Steam-Foren sind nicht hilfreich. Stand jetzt, sind 20,– Euro echt nur für Fanatiker lohnenwert.

Bis zum nächsten größeren Update werde ich die Finger davon lassen.

Herr Pahl, was machen Sie eigentlich beruflich?

Das ist tatsächlich eine bannig diffizile Frage, weil sie viele Antworten kennt, je nach Adressat und damit: je nach Differenzierung.

Beginner Level, zum Beispiel für meine verrentete Nachbarin oder nicht-technik-affine Verwandte:

Ich mach so Internet-Zeug. Websites und so

Medium Level, z.B. für Ärzte, bei denen man nicht sicher ist, ob es genuines Interesse oder die implizite Frage nach Liquidität und Einkommensverhältnissen ist.

Ich bin selbständig und arbeite innerhalb von Projektteams für Zeiträume von 3 bis 24 Monaten an größeren Websites. Dabei geht es um die Mitwirkung an Konzepten und Umsetzung von Designs für das sogenannte Frontend, also grob gesagt, das was der User im Browser sehen und bedienen kann.

Das reicht aber nicht für den Experten-Level, für potentielle Auftraggeber oder Projektmanager, aus. Mit inzwischen 20 Jahren Erfahrung auf dem Buckel, liegt mein Mehrwert oberhalb der bloßen Umsetzung von Frontend-Zeug.

Chris Coyier hat im Oktober in seinem Blogeintrag „The Widening Responsibility for Front-End Developers“ viele Fragen und Überlegungen aus seinem Projektalltag angerissen. Sie machen deutlich, wie komplex inzwischen der Weg von Konzept → Design → Umsetzung geworden ist. Das bildet auch meinen Projektalltag wieder.

Wenn Designs und Konzepte das erste Mal aufschlagen, fehlt es ihnen an „Praktikabilität“ und können daher nicht direkt in Code umgesetzt werden. Responsives Design (also anpassungsfähig an unterschiedliche Browser, Browserbreiten und Endgeräten) sind häufig ebenso nur Lippenbekenntnisse wie die Berücksichtigung von Barrierefreiheit-Anforderungen.

Designs werden häufig als komplette Seiten und nicht als wiederverwendbare Bausteine entwickelt. Es gibt auf Designseite häufig weder das Wissen noch die Werkzeuge für diesen „Komponenten-Gedanken“.

Und so besteht ein Teil des Jobs darin, schon vor dem Schreiben der ersten Zeile Code, auf Designs und Konzepte Einfluß zu nehmen. Zum Beispiel darauf zu drängen, dass Seiten systematisch und auf Bausteine-Basis aufgebaut werden. Es ist auch im Sinne des Kunden, wenn nicht jeder Seitentyp seiner Website von Grund auf, neu entwickelt werden muss (wir reden hier nicht über Portfolio-Websites, sondern Websites mit drei- bis fünfstelligen Seitenzahlen).

Ein Teil des Jobs ist, jedes vorgestellte Design auf die Umsetzungsfähigkeit abzuklopfen, bevor das Coding beginnt. Dazu gehört auch die gerne vernachlässigte Frage, wie sich die Komponente verhält, wenn es nicht die „ideale“ Menge an Content gibt. Was passiert bei einer langen Headline? Bei einer Copy, die nur aus einem Satz besteht? Wenn die Nutzungsrechte für das Bild abgelaufen sind?

Funktional erlebe ich es immer wieder, dass es in den Designs Probleme im Umgang zwischen Touch- und Non-Touchdevices gibt. Zum Beispiel wenn es Funktionalitäten gibt, die zwingend auf Hover per Maus angewiesen ist. Oder es wird fälschlicherweise angenommen, dass Browserbreiten mit der Unterscheidung zwischen Tisch- und Tabletgeräten einhergeht (nope, größere Tablets sind inzwischen breiter als schmale Laptops und bei Geräten wie MS Surface verwischt die Grenzziehung komplett).

An der Nahtstelle zwischen Design und Konzeption stehen auch Fragen der Umsetzung im Zusammenhang mit der verwendeten Software auf dem Server. Wenn es zwei ähnliche Komponenten gibt, ist es sinnvoll sie als zwei Komponenten getrennt anzulegen, oder handelt es sich um eine einzige Komponente mit zwei Ausprägungen? Was lässt sich mit der Serversoftware besser abbilden?

Vor der Umsetzung steht dann die Etablierung eines Workflows für die Umsetzung. Welche Werkzeuge werden genutzt, welche Rahmenbedingungen werden geschaffen, welche „Code-Regeln“ werden aufgestellt. SCSS? Semantische Klassen im HTML? Icons umsetzen als… Icon-Fonts, Inline-SVG oder SVG-Sprites?

Dazu gehört auch die Beratung mit dem Backend, wie sich z.B. die Kommunikation bei Serveranfragen durch den Browser gestaltet.


Projekte dieser Größenordnung haben mehrere Interessenten. Kommunikation ist ein Teil des Jobs: Interessenten wollen und müssen abgeholt werden. Es muss zwischen den unterschiedlichen Interessen vermittelt werden. Am Ende des Tages gibt es aber nur einen Interessenten, der die Rechnung zahlt. Die Kommunikation muss daher auch darauf ausgerichtet sein, dass seine Interessen gewahrt werden.


I apologize if I’ve made you feel a little anxious reading this. If you feel like you’re behind in understanding all this stuff, you aren’t alone.

In fact, I don’t think I’ve talked to a single developer who told me they felt entirely comfortable with the entire world of building websites. Everybody has weak spots or entire areas where they just don’t know the first dang thing. You not only can specialize, but specializing is a pretty good idea, and I think you will end up specializing to some degree whether you plan to or not.

Irgendwann in den Nuller Jahren, war ich mir nicht sicher, ob „Webdesigner“ ein Job mit Zukunft wäre. Agenturen gingen aggressiv auf den Markt um mit in Microsoft Word(!!) produzierten Websites Kunden zu ködern. Die Hamburger Arbeitsagentur hat damals massenweise arbeitslose Druckerei-Mitarbeiter in Webdesign-Fortbildungskurse gepackt. In meinen Alpträumen, sah ich irgendwelche Kinder von Firmenchefs am Rechner mit WYSIWYG-Editoren wie Frontpage herumspielen und mich aus dem Business schießen.

So ist es bislang nicht gekommen – weil mein Job mehr umfasst, als man es Laien in nur drei Sätzen erklären kann. Weil mein Job mehr als nur „Umsetzung“ ist und „Berater“ und „Konzepter“-Tätigkeiten beinhaltet. Weil der Job eben nicht nur aus „Nine to Five“ besteht, sondern aus dem Blick über den Tellerrand: was für relevante Technologien gibt es? Wird jQuery wirklich noch gebraucht? Was für Themen kommen in den nächsten Jahren?

Coyiers Blogeintrag macht schon durch die schiere Menge an Fragen deutlich, dass man auch dann genügend auf der Pfanne haben kann, wenn man kein sogenannter „Fullstack-Entwickler“ ist, der die komplette Bandbreite von Server bis Frontend/Browser abdeckt.

Coyiers Blogeintrag macht mir aber auch die Frage bewusst, wie man all diese Detailsfragen und Soft-Skills gegenüber potentiellen Auftraggeber anbringen kann, ohne dass man einen zehnseitigen Aufsatz schreibt. Sondern in eine Form bringt, die gleichberechtigt neben der tabellarischen Aufstellung der rein technischen Skills bestehen kann.

Was war. KW#48

Things I did.

Letzte Woche hatte ich Urlaub. Letzten Sonntag bin ich für drei Tage nach St. Peter-Ording (präziser: „Bad St. Peter“) gefahren, wo es mir vor zwei Jahren so gut gefallen hatte und was damals für meine „emotionale Hygiene“ so wichtig war. Diesmal bin ich nicht ganz so geflasht zurückgekommen.

  • Dieses Jahr lag der Urlaub ca. vier Wochen später. Diese vier Wochen zwischen Ende Oktober und Ende November machen bei den Läden/Restaurants vor Ort einen großen Unterschied. Viele Läden haben geschlossen oder ihre Öffnungszeiten verändert. Google Map is shit und die Websites der Geschäfte/Restaurants sind nur manchmal hilfreich.
  • Das Wetter war ein gelangweiltes Grau in Grau. So gut wie kein Wind – für Windstille bin ich eigentlich nicht an die Nordsee gefahren. So gut wie keine Sonne. Temperaturen im Niemandsland zwischen kalt und warm.
  • Drei Tage waren für Alltags-Detox zu wenig. Erst am dritten Tag fingen der Kopf an, den Alltag loszulassen – aber dann war auch schon Abfahrt. Mein Fehler.

Grundsätzlich bleibt aber die Landschaft geil – Spazierengehen durch die endlosen Weiten des Wattenmeers und Salzwiesen ohne eine Menschenseele zu treffen.

St. Peter Bad, Wattenmeer

Things I worked on.

Vor und nach dem Kurzurlaub hatte ich zwei Websites eines Kunden zu aktualisieren. Anlass war der Umzug des Geschäftssitzes. Für mich war das vor allem der Tritt in den Allerwertesten, endlich mit einem Vorhaben fortzufahren, was schon seit einem Jahr auf meiner To Do-Liste steht: das Umschwenken von (Kunden-)Websites weg von cloudbasierenden Webschriften von Typekit hin zu selbst gehosteten Schriften.

Typekit ist vor Jahren von Adobe übernommen worden. 2018 hat Adobe dann den Wechsel der Preisstruktur von Typekit weg, hin zu dem überteuerten Adobe Cloud-Rip-Off angekündigt, der für mich irgendwann 2020 in Kraft treten würde. Seit dem habe ich bei etlichen Schriftenbundles von „Design Cuts“ zugeschlagen, um ein Portfolio an Webfonts aufzubauen – nur für die Umstellung der Sites fand ich noch keine Zeit.

Die Umstellung der ersten Website nahm viel Zeit in Anspruch. Die Site ist 2004 entstanden und das Projekt wurde von mir fast auf den Tag genau, vor fünf Jahren, 2014, auf Grunt umgestellt – mit all den Problemen die es zB mit SCSS inzwischen macht. Grunt hat, ähnlich wie Gulp, inzwischen das Ende seiner Lebenszeit erreicht. Deswegen habe ich den Scope „Umstellung auf eigene Webfonts“ zu „Wechsel auf einen ’zukunftssicheren‘ (YMMV) Task-Runner“ aufgebohrt.

Als Frontend-Entwickler rauscht über Twitter und Newsletter immer eine gewisse Nachrichtenlage über angesagte Frontend-Dinge vorbei. Daraus entstand bei mir der Eindruck, dass WebPack in Sachen Task-Runner „state of the art“ sei und begann am Tag vor dem Urlaub, dieses mal anzutesten und Grunt raus- und Webpack rein zu schmeissen.

Am frühen Abend bekam ich dann die Kinnlade nicht mehr geschlossen – so erstaunt war ich über das Ergebnis, dass WebPack als Task Runner für Dinge jenseits eines JavaScript-Fokus im Grunde genommen nur ein notdürftiger Hack ist. Das für mich so offensichtliche Ergebnis, entsprach so gar nicht dem Bild, den viele Artikel im Frontend-Bereich vermitteln. Im Nachhinein erkläre ich es mir damit, dass viele Entwickler im Bereich der JS-Frameworks wie React, Vue, Angular & Co. mit WebPack einen Hammer bekommen haben und damit nur noch Nägel zum Reinschlagen sehen.

Meine Probleme mit der WebPack-Verwendung außerhalb der JS-Welt, zB für SCSS/CSS, Templating oder Assets-Verwaltung, erklären sich aus dem Aufbau von WebPack. Vereinfacht funktioniert WebPack so:

  1. WebPack arbeitet anhand einer selbst erstellten Konfigurationsdatei
  2. Dort werden Dateien werden als „Entrypoints“ eingetragen.
  3. Aus jeder als Entrypoint abgelegten Datei, extrahiert WebPack einen „Dependency Tree“ und holt sich alle weitere Dateien, die als „Abhängigkeit“ im Entrypoint verlinkt/importiert wurde. Diese Dateien werden in einem Workflow reingekippt. Je nach Dateinamen/-Endung/-Ort kann ein eigener Workflow aufgezogen werden.
  4. Der Workflow ist eine Abfolge von in der Konfiguration eingetragenen Modulen, die die reingekippten Dateien bearbeiten. Z.B. bei SCSS: mache aus SCSS-Inhalt einen CSS-Inhalt. Transformiere den CSS-Inhalt mit Autoprefixer.
  5. Das Endprodukt jedes Entrypoints ist eine JavaScript-Datei, die die Summe der durch den Workflow bearbeiteten, abhängigen Dateien enthält.

Die Betonung liegt auf: jede als Entrypoint abgelegte Datei produziert exakt eine Javascript-Datei. Ja, auch wenn ich eine SCSS-Datei als Entrypoint ablege und durch einen CSS-Workflow jage, ist das Endprodukt eine Javascript-Datei. Diese enthält CSS-Anweisungen, die in einem WebPack-Wrapper verpackt sind – wenig hilfreich.

Also muss am Ende des Workflows ein weiteres Modul eingehängt werden: MiniCssExtractor – der extrahiert aus der produzierten JS-Datei den CSS-Code und schreibt ihn in eine CSS-Datei.

Damit produziert WebPack also zwei Dateien: eine CSS-Datei und eine nutzlose JS-Datei. Um diese los zu werden, muss noch mal ein Modul am Ende des Workflows eingehängt werden, damit die nicht benötigte JS-Datei gelöscht wird – im Gegensatz zum MiniCssExtractor gibt es aber hier kein etabliertes Standard-Modul, sondern ein halbes Dutzend von irgendwelchen händisch zusammengeklöppelten WebPack-Modulen.

Genau diese Geschichte mit dem MiniCssExtractor und dem JS-File-Remove-Modul ist für mich die Quintessenz des WebPack-Missverständnisses. Es ist kein Task Runner, sondern ein JS-Module-Bundler. Fair enough, steht ja auch drauf. Aber das so viele das Ding als Task Runner vergewaltigen, hat mich schon verblüfft.

Selbst WebPack, 2012 gestartet, scheint das Task Runner-Thema erst jetzt auf den Schirm zu bekommen. Der MiniCssExtractor wurde im Mai 2019 Nachfolger des ExtractTextWebpack-Moduls, das im März 2018 durch Umstellungen in Webpack 4 gegen die Wand gefahren wurde. Das Problem mit der Produktion einer nicht benötigten JS-Datei soll irgendwann 2020 mit Webpack 5 behoben werden.

Aus Frontend-Sicht handelt man sich mit WebPack als Task Runner eine wackelige Plattform und eine hohe Abhängigkeit von der Weiterentwicklung notwendiger WebPack-Modulen ein (s.o., das Desaster rund um ExtractTextWebpack in WebPack 4). Man wechselt also seine Grunt-/Gulp-Abhängigkeit gegen WebPack-Fesseln ein.

An jenem Abend wurde mir dann klar, dass es nur einen Weg gibt, um die Abhängigkeiten zu reduzieren und flexibel zu bleiben: npm-Skripts.

npm basiert auf „pures“ NodeJS. Eingehängte Module können Shell- oder NodeJS-Skripts sein. Es werden keine speziellen Wrapper gebraucht, um sie für einen Grunt- oder Gulp-Task Runner lauffähig zu machen.

Dieser „Down to the Metal“-Ansatz stärkt zu dem das Kennenlernen der Shell und den grundlegenden NodeJS-Modules zB rund um das Datei-System.

Bookmarks

Was war. KW#41

Things I did.

Die Planungen der Woche mussten umgeschmissen werden, nachdem ein für Mittwoch geplantes Briefing von Kundenseite aus, um eine Woche verschoben werden musste und ich damit kurzfristig 2–3 Tage zur fast freien Verfügung hatte.

Einen Tag schmiss ich gepflegt weg, als ich mich um fehlenden Festplatten-Platz meines Desktop-Macs kümmerte (nur noch 18GB frei), um das XCode-Update (7GB) zu installieren.

Das Problem ist das völlig verkorkste Festplatten-Management unter OS X:

  • Der Finder zeigt unter „xxx GB verfügbar“ irrerweise nicht den tatsächlich verfügbaren Festplattenplatz an, sondern eine Zahl, die belegten, aber „löschbaren“ Festplattenplatz dazu addiert. Bei diesem “löschbaren” („cancellable“) Platz scheint sich um Backups, Caches und iCloud-Dateien zu handeln. Einen „Knopf“ zum Löschen gibt es nicht. Angeblich soll sich das System selber darum kümmern.

    Die tatsächliche Größe des freien Festplattenplatz erfährt man nur durch andere Tools oder per Kopfrechnen bei den Festplatteninfos: Festplattenkapazität minus Benutzter Platz.

  • Selbst nach „harten“ Löschen (am Papierkorb vorbei) zB. der 60GB Musik, wurde der unbelegte Festplattenplatz nicht größer. Nach einem Neustart schrumpfte der freie Festplattenplatz gar auf 7GB, ehe er im Laufe von 5 Minuten wieder auf 18 GB anwuchs – bar jeder Logik.

  • Der eigentliche Übeltäter ist die Time Machine, Apples Backup-System. Auch wenn er angeblich nur 7GB „backupen“ wollte – einige Minuten nach Ende des Backups waren dann plötzlich 150GB Festplatte frei.


Donnerstag, Freitag, Samstag habe ich mit Lesen von „Fachartikeln“ verbracht. Siehe unten.

Am Freitag habe ich für ein privates Projekt mit dem Endziel „React“ mal in die Themen MariaDB, ORM und Node.js reingeschnuppert und einen ersten Durchstich gemacht. Beim Evaluierung des Node.js-ORMs „Sequelize“ tauchte „LoopBack“ auf dem Radar auf und lockte mit großer Mächtigkeit und den magischen Worten „API-Endpoints“ auf – eine Evaluierung am Montag zeigte aber die Unbrauchbarkeit. LoopBack 4 sollte realistischerweiser nur mit TypeScript verwendet werden, und das ist mir im Kontext meines Endziels, zu weit aus dem Fokus raus.

Things I read.

Bereits am Donnerstag verbloggt, aber es treibt mich immer noch herum: Programming as Theory Building, ein Papier von Peter Naur von 1985. Demnach ist Code von Software nur ein „Artefakt“ der eigentlichen Arbeit eines Programmierers: dem Aufbau eines Verständnisses für die zu bewältigenden Problemen, den Anforderungen, den erforderlichen Funktionen und den Weg, den man beschreitet, kurz: dem Aufbau eines theoretischen Verständnisses der zu bauenden Software.

Dieser Blickwinkel hat Konsequenzen wie man mit Teammitgliedern/Kunden über das Software-Produkt spricht und wie man es dokumentiert. Anstatt sich in der Kleinteiligkeit von Code-Zeilen zu verlieren, gilt es Ideen, Ansätze und Motivation zu beschreiben.

1985 geschrieben, trifft er aber genau einer der Schmerzpunkte die ich als Frontendler mit der Zusammenarbeit von Designern habe, die auch 2019, kein „Theory Building“ entwickeln, sondern Photoshop- oder Sketch-Dateien liefern. Ich darf dann raten, ob die 512px breite Spalte fix 512px oder 50% der Viewportbreite eines Tablets breit sein soll – weil des Designers Liefergegenstand nur eine Zustandsbeschreibung eines Viewports liefert, aber nicht die übergeordnete Idee des Designers vermittelt, was er sich dabei gedacht hat.


Zu meiner Überraschung schneite in meiner Twitter-Timeline der Hinweis rein, dass Sass, der CSS-Transpilator, in der ersten Oktober-Woche das einschneidendste Update der letzten fünf Jahre erfuhr – und keiner meiner abonnierten Frontend-Mailinglisten hielt es bis heute für nötig darauf hinzuweisen.

Sass hat sich in seiner neuesten Version ein Modul-System angelacht – vorerst nur auf der „führenden“ Sass-Implementierung Dart-Sass (Libsass und damit Node-Sass hinken hinterher).

Dies wird IMHO das Arbeiten mit Sass auf komplett neue Beine stellen – aber zu meiner Überraschung herrscht in der Frontend-Szene Schweigen im Walde. Ein Artikel bei css-tricks.com mit schlappen 5 Kommentaren. Totentanz dagegen bei Reddit und Stackoverflow.

Mit dem neuen Modul-System über den Befehl @use will Sass Partials bzw Module so kapseln, wie man es von JS-Modulen gewohnt ist – also kein globaler Zugriff auf Dinge die in den Partials stattfinden, sondern nur explizit deklarierter Zugriff.

Per Bauchgefühl bin ich recht begeistert, denn mein Gros an Bezahlarbeit findet in sehr großen Projekten statt und der Einzug eines Scopes für Sass, hört sich auf dem Papier gut an. Aber nach Lesen der Dokumentation habe ich exakt null Gefühl für die tatsächliche Implementierung (wie verändern sich Projektstrukturen?) und den tatsächlich relevanten Vorteilen.

Macht JS-artiges Scoping Sinn für CSS und dem „scope-losen“ HTML-Markup? Was macht SCSS-Scoping mit custom properties oder Scopes wie Shadow DOM und <style scoped>? Da hätte ich mir vom Sass-Team etwas mehr Hinweise auf sinnvolle Anwendungen in der freien Wildbahn gewünscht – man komme mir bitte nicht mit „Theming“.

Things I watched.

Am Samstag lief den ganzen Tag der Stream des japanischen Auslandssender „NHK World“, die die Taifun Hagibis-Sondersendungen aus dem Inlandsfernsehen übernahmen und auf englisch simultan übersetzten.

Ich habe mir On-Air-Designs angesehen und einige Übersetzungs-App angesehen, die über die Handy-Kamera eingeblendete japanische Schriftzeichen „live“ ins Deutsche übersetzten.

  • In Japan ist der Farbcode für höchste Gefahrenstufe nicht Rot, sondern Violett und dann Schwarz.
  • Japanische Moderatoren tragen fast ausnahmslos Nadelstreifenanzüge.
  • Wenn ein*e Moderator*in auf etwas an einer Videowall zeigen will, dann wird nicht ein normaler Zeigestab genommen, sondern ein Stab mit einem dicken Bommel am Ende.
  • Das japanische Schriftsystem wird problemlos sowohl horizontal als auch vertikal eingesetzt – ein Traum für das Screendesign.

Am Sonntag habe ich die erste Folge von „Doom Patrol“ auf Amazon gesehen – nach der gleichnamigen Comic-Serie von DC. Heute habe ich die Folgen 2+3 gesehen. Ich denke, man tut gut daran, die ersten drei Folgen am Stück zu sehen, da erst die dritte Folge den vorherigen Folgen einen Zusammenhalt gibt. Auf der anderen Seite ist es eine Form der Vergeudung (oder Minutenschinderei) für jenen Zusammenhalt fucking drei Stunden zu brauchen.

Abschließendes Urteil steht noch aus – ich habe parallel mir das erste Trade-Paperback der Serie aus der Grant Morrison-Ära geholt, auf die sich auch die TV-Serie beziehen soll. Inhaltlich fängt es noch wüster an und zeichnerisch ist das dunkelstes US-Comic-Mittelalter.

Things I listened to.

Hinter der Paywall, hat die „Financial Times“ eine schöne Serie: „Life of a Song“, in der die FT auf die Geschichte eines Lieds und seiner Cover-Versionen eingehen. Diesmal ist es Sittin’ On The Dock of the Bay“ von Otis Redding.

Der Artikel hat mir noch stärker die Größe dieses Titels offenbart. Otis Redding verstarb bei einem Flugzeugunglück kurz bevor er die Produktion von „The Dock of the Bay“ abschließen konnte. Es war Steve Cropper, der aus den einzelnen Aufnahmen, den Song zusammen bastelte. Das ikonische Pfeifen am Ende war nur ein Improvisorium von Redding, der für diese Stelle später noch einen Text schreiben wollte.

Wie perfekt das Original, mit seinem depressiven Text ist, erkennt man an den zahlreichen zerschellten Cover-Versionen. Die blutleere Version von Willie Nelson und Waylong Jennings, die Kasperle-Version von T-Rex und Gloria Jones, die mit Rod-Stewart-Mayonaise zugekleisterte Variante oder die Vergewaltigung durch das Tom Jones-Vibrato (Props für die Einbindung von Steve Cropper) oder das testosteron-getriebene, bemühte „Method Acting“-Cover von Justin Timberlake (auch hier Props für die Einbindung von Steve Cropper).


Zur Entgiftung von den ganzen katastrophalen Cover-Versionen, hier eines der besten Cover der Musikgeschichte überhaupt: Tom Petty und Freunde mit „While My Guitar Gently Weeps“ bei der posthumen Aufnahme von George Harrison in die Rock & Roll Hall of Fame. Der schüchterne Junge an der Gitarre neben Tom Petty ist Dhani Harrison, der Sohn von George. Im hinteren Teil des Covers rückt dann Prince in den Vordergrund, der eines meiner Lieblings-Gitarren-Solos derart abfackelt, dass dem Harrison-Sohn die Freunde nur so aus den Augen sprüht. (Und Tom Petty ist sowieso die Idealbesetzung für den Gesang)

Watching: “A Branch in Time – a story about revision histories”

Gesehen: der Vortrag von der RubyConf.au „A Branch in Time – a story about revision histories“ von Tekon Süleyman.

Auf der Basis einer fiktiven Geschichte einer Entwicklerin, verdeutlicht Süleyman, welche zentrale Rolle Git in Projekten einnimmt – nicht nur als bloßes Source-Verwaltungs-Werkzeug, sondern idealerweise als Dokumentation, warum bestimmte Dinge im Code so umgesetzt worden sind, wie sie umgesetzt wurden. Das ist eine weitaus weniger banale Frage, als es sich für Außenstehende anhört.

Süleyman dockt seine Geschichte und Vorschläge an ein Thesenpapier von Peter Naur an: „Programming as Theory Building“ (PDF).

Programmieren ist demnach nicht die Produktion von Code, sondern der Aufbau einer Theorie oder eines Gedankenmodells, wie die Software zu arbeiten hat. Code ist demnach nur ein Artefakt/Ausdruck dieser Denkprozesse.

Software-Projekte werden fast nur noch iterativ (in kleinen Schritten) entwickelt. Schritt für Schritt wird innerhalb des Teams das oder die Gedanken-Modelle entwickelt. Aber es gibt keine Prozesse und kein Format, um die entwickelten Modelle expressis verbis niederzuschreiben und dann weiter zu entwickeln. Stattdessen handelt es sich um „institutional knowledge“, also eine Art kollektives Wissen, dass sich entwickelt.

An dieser Stelle ist Code der Ausdruck für eine konkrete Umsetzung: “was ist wie umgesetzt worden”. Git kann und sollte an dieser Stelle die Rolle spielen, die Motivation und Abwägungen, also das „warum ist es so umgesetzt worden“, zu dokumentieren. Für Git Commits gilt daher der Leitsatz: „Capture the why, not the what“.

Naur geht in seinem Papier so weit, und spricht von einem Sterben der Software, wenn das Entwicklungsteam aufgelöst wird. Mit dem Verschwinden des kollektiven Wissens, schwindet auch die Wartbarkeit der Software.


IMHO setzt der Zerfall von Software schon sehr viel früher ein: wenn unter Zeitdruck und/oder Komfort Abkürzungen genommen werden. Das Wissen wird statt eines „nachschlagbaren“ (dokumentierten) Kollektiv-Wissens, zu einem individuellen Wissen, zu einem Herrschafts-Wissen.

Es fängt mit Petitessen an. Aber wenn der Damm löchrig ist, ist der Dammbruch nicht weit.

Code-Reviews können nicht mehr sauber geführt werden, weil der zu prüfende „Soll-Zustand“ für den Reviewer nicht mehr nachzuvollziehen ist. Die Code-Review verkommt zu einem menschlichen Linting-Prozess.

Es schleichen sich immer stärkere Inkonsistenzen ins Projekt rein, weil es keine eindeutige Referenz mehr gibt, sondern mehrere entstanden sind. Es gibt mangels eindeutiger Referenz keinen Konsens mehr, was richtig oder falsch ist, sondern nur noch mehr oder weniger kompetente Interpretationen.

Das Entwicklungstempo wird abnehmen. Entwickler, die einen anderen Teilausschnitt des „kollektiven Wissens“ haben, werden den Code falsch interpretieren oder andere Rahmenbedingungen bzw. Maßstäbe anlegen und Probleme mit dem Bestandscode bekommen.

Ich weiß nicht, wie dieser Kreislauf rückgängig zu machen ist.

© 2024 Kai Pahl

Theme basiert auf „Lingonberry“ von Anders NorenNach Oben ↑