Shownotes & Links
- db-migrate: Bibliothek für Datenbankmigrationen
- pg: Postgres-Client
- globalize
- globalize-express
- express
- Sequelize ORM
- Debugging in VS Code
- Node.js Debugging in VS Code
- deno
- “Per Anhalter durch JavaScript” – Aufzeichnung des Vortrags von Lisa und Lucas auf der JCON 2020
- JavaScript verstehen und anwenden – unsere Online-Schulung mit Lisa und Lucas
Transkript
Robert Glaser:
So, herzlich Willkommen zum INNOQ Podcast. Neue Folge, also die erste Folge in 2021. Wir hoffen ihr seid alle super ins neue Jahr gekommen, mal gucken was uns in diesem Jahr alles so Spannendes erwartet. Ich habe heute auf jeden Fall ein spannendes Thema. Mich interessiert das brennend, ich hoffe euch auch und dazu habe ich mir meine Kolleginnen und Kollegen den Lucas Dohmen, den kennt ihr bestimmt, weil der hier auch diesen Podcast ganz oft moderiert und die Lisa Moritz eingeladen. Hallo ihr beiden!
Lucas Dohmen:
Hallo Robert!
Lisa Moritz:
Hallo Robert!
Robert Glaser:
So, die Lisa und der Lucas, die sind bei uns Consultants bei INNOQ, aber die machen auch…, also trainieren auch unsere neue JavaScript Schulung. Und deswegen dachte ich, es wäre doch toll, wenn ich die beiden mal hier bei mir habe und die mir vielleicht ein paar Fragen zu JavaScript oder dem Stand von JavaScript in diesem wunderschönen neuen Jahr beantworten können. Lucas, ich spreche dich jetzt einfach mal an, weil ich mal was zur Geschichte von JavaScript wissen will. Ich bin da nicht ganz unbefleckt, ich habe selber schon relativ viel mit JavaScript gearbeitet, in der letzten Zeit nicht mehr so viel. Aber die Sprache ist uns allen ja wahrscheinlich positive, wie negativ in Erinnerung. Oder zumindest schon bekannt. Warum ist denn das eigentlich so? Warum hat JavaScript so einen weirden Ruf, sage ich mal? Warum feiern das viele total ab und viele machen sich darüber lustig? Warum ist das so? Bei anderen Programmiersprachen ist mir das nie so deutlich aufgefallen.
Lucas Dohmen:
Ja, also ich würde schon sagen, es gibt auch andere Programmiersprachen, bei denen das so ist. Also mir würde auf jeden Fall noch PHP einfallen, über das sich auch immer sehr viele Leute lustig machen.
Robert Glaser:
Stimmt!
Lucas Dohmen:
Das sind so glaube ich die zwei Sprachen, bei denen das am meisten passiert, würde ich jetzt mal sagen. Genau, aber JavaScript hat halt wirklich eine sehr ungewöhnliche Geschichte. Es ist aus einem ganz großen Zeitdruck heraus entstanden am Anfang der Browserkriege zwischen Internet Explorer und Netscape. Wo es darum ging, wer wird der dominante Browser im Web? Und in dieser Zeit ging es dann halt darum, man hatte schon HTML und CSS, wie macht man die Seite dynamisch? Wie kann man da irgendwie irgendwas hinzufügen, was der andere Browser nicht hat? Also halt einfach dann zu sagen: Hey, diese Webseite, die kann nur funktionieren in meinem Browser. Der ist ja viel cooler und der ist viel interaktiver. Und aus diesem Druck heraus haben halt beide Firmen, also Microsoft und Netscape angefangen irgendwie auszuprobieren was zu finden, womit man das scripten kann. Irgendwas mit Visual Basic bei Microsoft und ja, bei Netscape war es halt JavaScript. Daraus geboren, dass damals halt Java die coole neue Sprache ist, heute schwer vorzustellen, aber damals war es das, sollte es halt so ein bisschen aussehen wie JavaScript… äh, wie Java. Aber halt leichtgewichtiger, einfacher zu lernen sein und zu dem halt auch ein bisschen mit Java zusammenspielen können. Also damals gab es dann ja so Java Widgets, wie hießen die? Ich habe den Namen vergessen.
Robert Glaser:
Applets, oder?
Lucas Dohmen:
Applets, genau! Um die halt zu scripten, um mit denen irgendwie zu interagieren aus der Website heraus, dafür war JavaScript halt auch gedacht. Was halt auch am Anfang das Konzept beeinflusst hat. Und zugleich war aber der Erfinder der Sprache nicht so ein Fan von Java, sondern eher von so Sprachen wie Scheme und Self und wollte die natürlich in seine Sprache miteinbringen, ohne… Aber musste halt trotzdem diese Management Anweisung: ‚soll bitte so aussehen wie Java‘, erfüllen. Und aus diesem komischen Mix heraus ist eine Sprache entstanden, die sehr ungewöhnlich war und wie ich schon sagte, es gab Zeitdruck, also er hatte 10 Tage Zeit die Sprache auszudenken und zu implementieren. Ich weiß nicht wer von euch schonmal in 10 Tagen eine Programmiersprache entwickelt hat, ist auf jeden Fall nicht so super viel Zeit. Wenn man das jetzt vergleicht mit so einer Sprache wie Clojure, wo irgendwie so ein Typ ein Jahr lang in irgendeiner Hängematte rumgelegen hat und nachgedacht hat, bevor er die erste Zeile geschrieben hat, dann ist das schon ein bisschen was anderes als in 10 Tagen unter vollem Druck so eine Sprache zu bauen. Und auch das erklärt natürlich viele Fehler, die damals passiert sind. Also will ich ihm gar nicht irgendwie ankreiden, ich glaube das würde uns allen passieren, wenn wir so kurz Zeit hätten. Und dann halt auch noch mit dem absurden Problem, dass Microsoft halt dann nachziehen wollte und natürlich diese Sprache als Blackbox nachgebaut hat. Also geguckt hat so: Wie verhält es sich, wenn ich das mache? Wie verhält es sich, wenn ich das mache? Weil das war ja nicht spezifiziert. Und dann halt auch Bugs quasi nachgebaut hat und natürlich auch neue Bugs reingebracht hat. Und erst wesentlich später haben sich diese zwei Firmen halt zusammengesetzt und gesagt: Hey, wie wäre es denn, wenn wir mal einen Standard zusammenbauen. Und dieser Standard heißt ECMAscript und da wurden natürlich viele von den Bugs von beiden Seiten standardisiert. Und die sind halt bis heute da und wie man sich vorstellen kann so eine Sprache, die so verbreitet ist, die in jedem Browser drin ist muss einfach rückwärtskompatibel sein, weil es einfach auch unendlich viel Code gibt, der im Internet rumfliegt. Das heißt der JavaScript Code, der halt vor 20 Jahren geschrieben wurde, soll heute auch noch funktionieren und das ist natürlich auch noch eine besondere Herausforderung. Da kann man nicht sowas machen wie jetzt bei Python 3.0 zu sagen: Hey, wir bauen mal irgendwie diese print-Funktion um. Oder so. Das würde halt nicht funktionieren, da würde das ganze Internet zusammenbrechen, das Web zusammenbrechen. Und das macht es natürlich auch zu einer besonderen Herausforderung. Und ich glaube das ist so ein bisschen der Grund warum die Sprache ein bisschen komisch ist, sage ich jetzt mal.
Robert Glaser:
Aber man kann ja auch sagen, also den blöden Spruch bemühen: Nur unter Druck wird Kohle zum Diamanten. Lisa, was gibt es denn für Diamanten in JavaScript? Jetzt hat der Lucas so ein bisschen in der Vergangenheit gewühlt und gesagt, dass auch Bugs standardisiert werden konnten oder wurden. Wenn wir uns mal den Positiven zuwenden, was sind denn so Diamanten oder Kernkonzept der Sprache?
Lisa Moritz:
Da würde ich gerne einmal ganz persönlich anfangen. Für mich ist JavaScript an sich schon der Diamant, weil das mich dabei unterstützt einfach so Code zu schreiben, wie ich denke. Ich muss nicht erst über tausende Abstraktionslevel mir irgendeine kleine Klasse aufbauen, wo ich dann eine Funktion reinballere, aber erst nach fünf Vererbungsketten oder was auch immer, mit 10 Interfaces vermische. Ich kann einfach genau das, was ich denke in eine Funktion kippen und es tut es genauso und ich muss nicht erst noch irgendwelche Umwege über diese Sprache gehen. Das macht für mich JavaScript auf jeden Fall superpraktisch und besonders. Und viele von den Bugs, die der Lucas eben erwähnt hat oder von den, sagen wir mal Vergangenheitsfeatures, die wurden ja mittlerweile durch irgendwelche Verbesserungen irgendwie ein bisschen ausgemergelt. Also jetzt zum Beispiel mit dem var, was irgendwie total global gescoped war, wurde mittlerweile ja let und const eingeführt und man kann viel sauberer damit arbeiten mittlerweile. Oder auch mit dem ==, man verwendet es halt einfach heute nicht mehr und weiß man verzichtet auf diese automatische Typenkonvertierung und macht dann einfach immer nur das === an der Stelle. Und genau, also ich glaube, ja es hat eine schlimme Vergangenheit haben einige von uns oder auch Dinge, die so passieren, aber man kann gut damit arbeiten, weil eben an JavaScript sehr viel gearbeitet wurde und es steht einen überhaupt nicht im Weg, wenn man irgendwelche Dinge umsetzen möchte. Klar, gibt es irgendwie wunderliche Sachen, an die man sich gewöhnen muss, wie zum Beispiel die Prototypenvererbung, das ist ja eher… ja sehr besonders, gerade wenn man aus dem Java Umfeld kommt, aber so mit dem was die Sprache mitbringt kann man sehr einfache, sehr gut lesbare und auch vor allen Dingen kleine Codebases schaffen, die schnell verstanden werden können und super wartbar sind dadurch auch.
Lucas Dohmen:
Ja und ich würde dazu auch noch ergänzen, was auch dadurch einfach, dass der große Wettkampf existiert hat zwischen den verschiedenen Browserherstellern, also gerade als dann auch Google mit Chrome eingestiegen ist in den Wettkampf, ist diese Sprache unglaublich schnell. Also da es eine dynamisch typisierte Sprache ist, ist es wirklich unvergleichbar schnell. Also natürlich ist es nicht so schnell wie jetzt ein C-Programm und was weiß ich, aber wenn man es mit Ruby oder Python vergleicht oder auch mit PHP vergleicht, ist diese Sprache wirklich sehr performant. Also auch, wie Lisa sagt, auch dieses kleine Programm, das man dann geschrieben hat, das kann dann halt echt schon ordentlich performen. Und auch viele Requests beantworten, wenn es jetzt eine Webanwendung ist oder so und das macht es natürlich auch attraktiv. Also mit einfach zu verstehendem Code halt eine ziemlich schnelle und coole Anwendungsform.
Lisa Moritz:
Was wir jetzt super oft gehört haben ist irgendwie clientseitiges JavaScript und kleine Projekte. Und ich habe ein bisschen Angst, dass das bei den Zuhörerinnen und Zuhörern hängen bleibt, dass man JavaScript genau dort einsetzen kann. Ich habe meine meisten Erfahrungen in JavaScript Back-End mit Node gemacht und bin damit super zufrieden. Und von meinen kleinen selbst gedaddelten Telegram-Bot bis hin zu einem großen Kundenprojekt ist das auf jeden Fall sehr gut einsetzbar, gut strukturiert, gut lesbar und eben sehr effizient programmierbar. Das würde ich gerne noch ergänzen.
Robert Glaser:
Bei mir war das ähnlich, ich habe JavaScript super lange nur clientseitig benutzt und irgendwann hatte ich mal ein relativ großes Kundenprojekt mit JavaScript im Back-End, das ging über, ich glaube Jahre. Und da habe ich JavaScript de facto nur im Back-End verwendet und hätte ich vorher auch nicht gedacht oder gesehen oder für möglich gehalten, was es da alles so gibt und dass man das tatsächlich sehr gut kann. Aber wenn wir nochmal zu den Diamanten, die angesprochenen, zurückkommen. Lisa, du hattest das auch kurz erwähnt: Die prototypische Vererbung. Was ist denn das eigentlich genau Lucas? Kannst du das erklären?
Lucas Dohmen:
Ja, also wenn man an Vererbung denkt, dann gibt es eigentlich so bei fast allen Programmiersprachen die klassenbasierte Vererbung. Das hat sich so ergeben, würde ich jetzt einfach mal sagen. Also das ist mehr so diese Smalltalk Tradition, wahrscheinlich noch… gibt es da irgendwie jetzt noch jemanden, der sagt: Ne, ist Simula. Oder irgendetwas, ist mir auch egal. Aber so in diesem Weg, wie wir das in Java kennen, wie wir das in Ruby kennen, Python und so weiter, das ist sehr ähnlich wie es funktioniert. Natürlich nicht gleich, aber sehr ähnlich, wie es funktioniert. Du schreibst eine Klasse und du machst Instanzen zu dieser Klasse. Das heißt also es gibt zwei verschiedene Konzepte: Eine Klasse und ein Objekt sind zwei verschiedene Dinge. Und wenn du halt vererben willst, dann machst du das auf dieser Klassenebene und wenn du dann eine Instanz erzeugen willst, dann machst du das auf dieser Instanz Ebene. Und in JavaScript funktioniert das anders. In JavaScript ist es tatsächlich so, dass alles ein Konzept ist. Also es gibt nicht zwei verschiedene Kategorien, sondern es gibt eine große Kategorie und das ist das Objekt. Und du kannst jetzt einfach sagen: Dieses Objekt hier, das hat einen Prototypen. Und das ist eigentlich nur so ein Zeiger auf ein anderes Objekt und das ist so: Wenn ich nicht weiß, wie es geht, frag doch mal den! Das ist quasi alles, was das tut. Also sagen wir mal wir haben ein Objekt und wir fragen den: Was ist dein Attribut Alter? Dann sagt das: Okay, mein Alter ist 12, hier ist 12. Und jetzt frage ich denen: Was ist denn dein, das Baujahr? Dann sagt der: Weiß ich nicht. Dann fragt er erstmal in der Prototypenkette das nächste in der Kette und wenn das das weiß, dann gibt er das als Antwort zurück. Und wenn nicht, fragt der wieder seinen Prototypen und irgendwann endet die Prototypenkette, und zwar bei den Objekt Prototypen. Der ist quasi das letzte in der Kette, hat quasi keinen Prototypen mehr. Und wenn der es nicht beantworten kann, dann wird undefined zurückgegeben. Das ist das ganze Konzept und das funktioniert deswegen, da halt im JavaScript, Objekte sind halt einfach ein Key-Value pair, also man hat immer irgendeinen Key und irgendeinen Value und dadurch kann man halt einfach nach einen Key fragen. Und wenn die Frage nicht beantwortet werden kann, dann wird die Frage einfach weitergegeben. Das ist eigentlich schon alles, also das ist das gesamte Konzept. Ich würde behaupten, eigentlich ist das Konzept einfacher als klassenbasierte Vererbung, weil man muss halt nicht über sowas… Also man muss überhaupt nicht über Klassen reden, eigentlich muss man nur darüber reden, wie es weitergehen wird. Aber für jemanden, der oder die Klassen gewohnt sind, ist es halt sehr ungewohnt, weil man halt sagt: Hä, wo sind denn jetzt meine Klassen? Und deswegen ist es einfach komisch. Also es ist nicht…, ich würde nicht sagen, dass es ein schlechteres Konzept ist. Es ist einfach ein anderes Konzept und dadurch, dass es sich nicht durchgesetzt hat so als Prinzip, ist es halt für die Leute, die aus einer anderen Sprache kommen, schwerer zu lernen. Aber ich glaube für jemanden, der das als erstes lernt, ist das gar nicht so irritierend, dass das so ist. Genau und das kommt halt aus dieser Self Sprache, die halt heute, glaube ich, wirklich niemand mehr programmiert, aber vielleicht gibt es ja doch noch wen. Und die einzige Sprache, die ich kenne, die prototypbasiert funktioniert, die halt irgendwie größere Verbreitung hat, ist JavaScript. Und dadurch hat es halt diese Sonderstellung. Und das wurde halt jetzt auch nochmal ein bisschen, ich würde sagen ein bisschen komplizierter gemacht, dadurch dass JavaScript versucht hat so ein bisschen sich zu öffnen gegenüber diesem üblichen Paradigma der klassenbasierten Vererbung und da dieses Class-Konstrukt eingeführt hat, aber trotzdem die prototypische Färbung behalten hat.
Robert Glaser:
Das wollte ich gerade fragen. Weil ich kenne ja Stand 2021, also eigentlich schon letztes Jahr und ich glaube sogar noch in 2019 und wenn nicht sogar noch früher, gab es irgendwann mal eine Syntax-Erweiterung. Die hat man ES2018, dann mal 2020 genannt, ich glaube die hieß dann irgendwann nur noch ESNext, ist das richtig?
Lucas Dohmen:
Nein, Robert.
Robert Glaser:
Okay. Falsch verstanden, aber man sieht, das kann wahnsinnig verwirrend sein. Es gab auf jeden Fall irgendwann, gibt es ja immer ab und zu mal wieder, größere Syntax-Erweiterungen in der Sprache. Und da hast du gerade erwähnt, es gibt jetzt eine Class Definition. Aber du hast vorher gesagt: Eigentlich gibt es gar keine Klassen, es gibt nur Prototypen. Was kann ich denn jetzt mit der Class Definition eigentlich tun?
Lisa Moritz:
Man kann… Also das ist quasi genau das gleiche, wie mit der Prototypen Vererbung, nur eben jetzt mit diesem syntaktischen Zucker der Class…, also dieses Class Namens. Also wenn du aus einer anderen Sprache nach JavaScript kommst, bist du nicht mehr so abgeschreckt, weil du Prototypen siehst, sondern eben Class liest. Bist dann aber spätestens zwei Tage danach abgeschreckt, weil das Class nicht so funktioniert, wie du denkst, weil eben genau diese prototypischer Vererbung dahinter steckt. Das ist quasi nur damit das für dich als objektorientierten Entwickler etwas angenehmer ausschaut als vorher. Also genau, das ist ein bisschen gefährlich an der Stelle.
Lucas Dohmen:
Genau.
Robert Glaser:
Das heißt, das ist eigentlich nur Syntax-Zucker und warum haben die das dann Class genannt das Keyword und nicht einfach Prototype?
Lucas Dohmen:
Also ich denke… also auch wenn man sich das anschaut und dann Java Code daneben legt, dann würde man wahrscheinlich sich sehr daran erinnert fühlen. Also das… so diese Class Definition ist quasi wie ein Class Definition in Java nur das halt die ganzen Typannotationen fehlen. Wenn man dann noch TypeScript dazu nimmt, dann ist man quasi bei Java. Also nicht ganz, aber schon ziemlich nah dran. Und ich glaube einfach dadurch, dass Java immer noch eine der populärsten Programmiersprachen ist und dass einfach viele Leute kennen, wurde sich daran einfach sehr, sehr stark angelehnt. Also wenn man das aus Java kennt, dann kann man das auch sehr schnell auch in JavaScript einfach übernehmen. Und ich glaube auch jemand, der halt Ruby oder Python programmiert, wo das halt anders aussieht eine Class zu definieren, würde sich trotzdem sehr schnell irgendwie das ummappen können aus seiner präferierten Sprache, sage ich jetzt mal. Also ich glaube es ist tatsächlich um dieses: Mein Gott, ich muss hier irgendwie Prototype hinschreiben, das gefällt mir nicht! Um diesen Effekt abzuschwächen dafür ist das hauptsächlich gemacht. Und das hat einen ganz netten Nebeneffekt und das sind so größere Vererbungshierarchien, da ist das ein bisschen einfacher mit diesen Class Ding. Aber das ist nicht gut zu erklären ohne Code, deswegen würde ich das jetzt überspringen. Aber grundsätzlich ist es glaube ich einfach um wieder mehr wie Java auszusehen, dass ist ja auch so ein bisschen die Historie von JavaScript, wurde das halt vor allem gemacht und es hat definitiv auch ein bisschen Nachteile. Wenn man einmal verstanden hat, was dahintersteckt, ist glaube ich die Class Syntax gar nicht schlecht, weil man damit das auch ein bisschen kürzer und cooler ausdrücken kann. Aber ich glaube manchmal ist es ein Problem, dass Leute das nicht wissen, was dahinter passiert und dann halt falsche Erwartungen daran haben. Das ist halt immer so ein bisschen das Problem, dadurch dass das halt so aussieht, wie man es gewohnt ist, aber nachher ein bisschen anders funktioniert, ist es halt blöd. Das ist ähnlich beim vis beispielsweise, das andere große Beispiel würde ich sagen, wo man was sieht, was so aussieht wie was man kennt, aber nachher im Detail funktioniert das anders. Also es funktioniert irgendwie in 90% oder 95% der Fälle genauso, wie du denkst und in 5% der Fälle funktioniert es dann anders. Und da bist du dann einfach verwirrt.
Robert Glaser:
Okay.
Lisa Moritz:
Ich habe gerade glaube ich noch einen coolen Vorteil von Class der mir gerade einfällt. Man kann das zu dokumentationszwecken sehr, sehr gut verwenden. Also wenn du im großen Team programmierst und du schreibst Funktionen, dadurch das JavaScript ja untypisiert ist weißt du erstmal nicht was reinkommt und was rausgeht. Aber wenn man irgendwelche Result-Objekte zum Beispiel bastelt, wo eben genau die Dinge drinstecken, die wir brauchen, dann ist das super hilfreich einfach als Dokumentation für die Entwicklerinnen und Entwickler, die nach einen kommen und das verwenden müssen.
Robert Glaser:
Ah, okay. Jetzt haben wir ein bisschen über Prototypen, Klassen, die es ja eigentlich nicht gibt, aber das Class Keyword gesprochen. Aber es gibt ja noch mehr Diamanten in dieser schönen Sprache. Zum Beispiel habe ich ja noch eine funktionale Facette, oder? Also ich kann Funktionen erstellen und die wirklich auch rumreichen, rumschicken, ohne sie gleichzeitig auszuführen, sie erst später ausführen oder es kann Funktionen hin- und herschicken, die wiederum Funktionsreferenzen retournieren und irgendwann verliere ich total den Überblick wie viele runde Klammern ich hinten anhängen muss, damit der Rückgabewert einer Funktion, der vielleicht wieder eine Funktion ist, dann tatsächlich auch ausgeführt wird oder eben nicht. Lisa, du hast gesagt JavaScript ermöglicht dir deine… macht dir wenig Vorgaben und ermöglicht dir eben deine Programme so zu gestalten, wie du das willst. Verwendest du da auch diese funktionalen Aspekte? Also freuen die dich, dass sie da sind?
Lisa Moritz:
Ja, kommt drauf an. Beliebte Antwort in unserem Bereich. Also klar, ich verwende das auch. Das kommt drauf an, ob ich… Also manchmal gebe ich Funktionen mit, manchmal nicht, das ist immer ein bisschen abgängig von dem was ich erreichen möchte. Was ich an der Stelle ganz cool finde ist, dass es auch hier einen syntaktischen Zucker gab bei den letzten ECMAScript, und zwar diese async/await Syntax. Also vielleicht viele von den Zuhörerinnen und Zuhörern, die jetzt länger nicht mit JavaScript gearbeitet haben, kennen noch diese callback Hölle mit irgendwelchen catches und thens und das wird immer tiefer verschachtelt. Und wenn ich das Ergebnis habe, dann gehe ich noch weiter und man hat so einen richtigen Baum und weiß nachher gar nicht mehr was wann passiert und kann es kaum noch lesen. Und das wurde durch die async/await Syntax ziemlich behoben. Da kann man einfach sagen: Ich habe eine asynchrone Funktion, die mir später Promise zurückliefert und ich warte einfach mit einem await auf das Ergebnis dieser asynchronen Funktion und kann danach damit weiterarbeiten. Dadurch hat man zwar noch weiterhin diese… eigentlich diese alten Promise Geschichten mit denen man gearbeitet hat, aber praktisch hat man jetzt einen viel besser lesbaren und besser verständlichen Code, als man das mit dieser callback Hölle noch hatte.
Robert Glaser:
Also ich kann das quasi flachklopfen, wenn ich async/await verwende?
Lisa Moritz:
Genau! Genau das kannst du tun.
Robert Glaser:
Und ich benutze das so, dass ich vor meine Funktion, die ich mir eben irgendwo erstelle, schreibe ich ein async Keyword und dann weiß die Maschine, das ist eben eine Funktion, die asynchron antwortet. Und wenn ich die irgendwann aufrufe, dann muss ich await davor schreiben, wenn ich will, dass das Programm wartet, bis diese asynchrone Funktion ausgeführt wurde, richtig?
Lisa Moritz:
Genau, genau.
Robert Glaser:
Okay. Also async/await ist so ein neues Feature, was diese funktionalen Aspekte der Sprache ein bisschen einfacher macht, zumindest was die Syntax angeht und wir als Entwickler müssen uns ja eben die Syntax schreiben. Also meine persönliche Erfahrung ist, dass es das wirklich einfacher macht. Ich hatte nämlich mal mir ein full stack Framework zusammengebaut, um eben eine Back-End Anwendung in JavaScript zu schreiben, da musste eine ORM hinzufügen, also ein Datenbank-Objekt-Mapper. Und der basierte komplett auf diesem Konzept der Asynchronität, weil ich hab mit einer Datenbank eben ein externes System an meinem Programm dran, wo ich nicht weiß… oder wo die JavaScript Engine eben nicht weiß, wann kommt denn jetzt das query result zurück? Und da habe ich sehr viel mit async/await gearbeitet und das eben auch zum ersten Mal kennengelernt. Und das fand ich relativ angenehm. Habe erstmal mit promises angefangen, das war einfach die Hölle. Also selbst einfache Abfragen und deren Fehlerfälle, die man ja auch bedenken muss, das hat zu absurden Baustrukturen geführt. Vielleicht habe ich es auch falsch gemacht, aber als ich dann async/await gefunden habe, war das echt sehr viel angenehmer. Habt ihr ähnliche Erfahrungen gemacht?
Lisa Moritz:
Ja, genau. Ich hatte das auch genau in dem Zusammenhang eben mit den Datenbankstrukturen, dass ich da angefangen hatte das mit dem klassischen promises eben umzusetzen und mit thens und so weiter. Und dann habe ich dieses util.promisify, heißt da glaube ich, entdeckt, womit man Dinge auch einfach so ummodeln kann, dass alles mit async/await verwendet werden kann. Und dadurch, dass man async/await hat, hat man schon nur noch eine Struktur und um die Fehlerfälle aufzudecken, kann man einfach ein try/catch darum tun, was einfach superpraktisch ist.
Lucas Dohmen:
Also ich würde noch kurz ergänzen, damit keiner oder keine von den Hörenden verwirrt ist. Also ich glaube Lisa und Robert haben gerade so ein bisschen callbacks und Promises durcheinandergeworfen. Aber… Also grundsätzlich, also das aller älteste sind die callbacks und dann kamen die Promises und mittlerweile kann man promises mit async/await verwenden. Genau. Aber also ich hatte halt auch ein größeres Projekt, da waren promises noch ganz, ganz neu und das war auch mein erstes größeres Node-Projekt. Und das war auf jeden Fall eine Herausforderung mit den callbacks und die Promises haben das schon verbessert, weil man zumindest mal besser ausdrücken konnte: Ich habe hier irgendwie fünf Dinge, die passieren und wenn alle davon fertig sind, möchte ich etwas Neues machen. Was, wenn man nur callbacks zur Verfügung hat echt blöd ist. Also echt unübersichtlich wird, man muss sich irgendwelche Helfer dazu basteln, damit das funktioniert. Das ist wirklich unschön und Promises haben das auf jeden Fall verbessert. Und auch heute benutze ich manchmal noch wirklich Promises ohne async/await, um halt bestimmte Sachen auszudrücken, wie jetzt: Diese drei Dinge sollen zuerst fertig werden und dann die zwei können was später fertig werden und so weiter. Das ist halt mit async/await, kann man das nicht ausdrücken, aber in wirklich fast allen Fällen kann man es damit tun und macht den Code wirklich sehr, sehr schön lesbar und das hilft auch gerade auch Leuten, die damit noch nicht soviel gemacht haben, mit callbacks und so weiter, total den Code zu verstehen, weil der ja einfacher zu verstehen ist. Aber ich weiß noch Lisa, wir hatten das auch mal. Wir hatten zusammen so ein Debugging, async/await kann manchmal halt auch blöd sein, wenn man dann an einer einzigen Stelle dann irgendwie ein await vergisst, weil man gar nicht das Ergebnis von dem Call braucht, sondern ich glaube das war irgendetwas mit einer Datenbanktransaktion, wo man erst warten musste, dass die eine Sache fertig wurde und dann sollte es weitergehen. Und dadurch gab es so eine race condition, die zu ganz, ganz blöden Fehlern geführt hat und das kann manchmal halt auch unschön sein. Also ich glaube, dass ist jetzt so der Fall, der mir am meisten im Kopf geblieben ist, weil das so ein langes Debugging war, wo wir zwei da zusammen drangesessen haben und geguckt haben: Warum passiert das? Und nachher dann dadurch steppen mussten mit einem Debugger, um überhaupt zu verstehen, warum das immer so und manchmal so passiert. Und der Debugger das dann auch noch wieder gefixt dadurch, dass er ja so langsam ist war das dann nicht zu beobachten. Das war ganz blöd. Naja, also das ist nicht immer supercool. Aber so von der Benutzung und von der Lesbarkeit finde ich es schon echt einen riesen Fortschritt.
Robert Glaser:
Also man muss wissen, wann man warten muss?
Lucas Dohmen:
Genau.
Robert Glaser:
Wenn man das nicht weiß, wartet man nicht und dann läuft es einfach durch. Und man erwartet dann was an einer anderen Stelle reinläuft, aber dann läuft er da doch nicht rein und das hat es bei euch wahrscheinlich kompliziert gemacht.
Lucas Dohmen:
Genau.
Robert Glaser:
Okay, das kann weird sein. Aber was manchmal noch viel weirder sein kann, finde ich persönlich ja: This. Das kennen viele die JavaScript benutzt haben, schonmal reingeschnuppert haben oder das schon länger benutzt haben auf this stößt man immer wieder und das hat, wenn ich das richtig verstanden habe, auch eine recht wichtige Funktionalität der Sprache, eine wichtige Facette. Weil es eben so der wichtigste Zeiger auf den Kontext ist. Also wir haben ja funktionale Facetten der Sprache, wir haben jetzt auch gehört, ich kann mir an beliebiger Stelle Funktionen definieren und die auch durch die Gegend werfen. Also die leeren Referenzen und irgendwann dann aufrufen oder halt nicht. Und this ermöglicht mir immer auf den aktuellen Kontext zu zeigen. Also entweder ich bin in einem Funktionskörper oder ich bin darüber in einem anderen Funktionskörper oder ich bin an einer ganz anderen Stelle und this sollte eigentlich immer auf den aktuellen Kontext zeigen. Nur manchmal verschiebt sich der Kontext und this zeigt dann nicht auf this, was ich erwarte, sondern auf that, das gibt es nicht. Aber es zeigt irgendwie auf was anderes. Ich habe gelernt in diesen neuen Spracherweiterungen, die wir vor einigen Minuten besprochen haben, gab es ja auch neue Syntax nicht nur das Class Keyword, sondern ich konnte meine Funktionen anders definieren. Und zwar musste ich nicht mehr function und dann den Namen meiner Funktion schreiben, um eine aufzubauen, sondern ich konnte einfach runde Klammern und dann mit einem rocket operator oder einen Gleichzeichen und einer spitzen Klammer nach rechts eine Funktion aufbauen. Und wenn ich das gemacht habe, hat das this ein anderes Binding als würde ich es mit dem alten function Wort tun, richtig? Warum ist das so?
Lucas Dohmen:
Also wenn du… Also this ist auch wieder so einer von den Sachen, die wurde halt in der Sprache so aufgenommen, um so auszusehen wie Java, aber sich dann schlussendlich nicht so verhält. Und das ist das verwirrende daran. Ich glaube, dass die… Vermutlich wäre es besser gewesen das Ding irgendwie anders zu nennen als this, weil das einfach zu Verwirrung führt, dass sich das eben nicht so verhält wie jetzt this in Java oder self in Ruby oder das Konzept gibt es ja in vielen objektorientierten Sprachen, weil es eigentlich auch nämlich nichts mit Objekten zu tun hat. Das ist das verwirrende daran, man würde immer irgendwie denken this ist das Objekt selbst, aber das ist es halt nicht. Sondern this hängt davon ab, wie die Funktion aufgerufen wurde und der einzige Grund, warum das so verwirrend ist, ist, dass es halt so einen magischen Zaubertrick gibt, der das this selbst setzt und der führt glaube ich eigentlich zu der Hauptverwirrung. Also wenn wir eine Funktion aufrufen, dann können wir bestimmen was das this ist. Also wir haben eine Funktion, dann könnten wir die aufrufen mit der… Also so können die call Funktion auf der Funktion aufrufen und einfach sagen: Das ist dein this. Und auf diese Art und Weise können wir das einfach steuern, was das this ist, wenn diese Funktion aufgerufen wird, und zwar pro Aufruf und nicht für die Funktion, sondern pro Aufruf machen. Und JavaScript macht automatisch call auf this, wenn vor dem Namen der Funktion ein Objekt Punkt steht, dann wird automatisch das, was da vor dem Punkt steht zu dem this. Und auf diese Art und Weise funktioniert das in den meisten Fällen so wie man erwartet, weil man sagt halt irgendwie: objekt.methodenname. Und zack wird das this auf das Objekt gesetzt. Also genauso wie man es erwartet. Aber wenn man dann halt das macht, was man dann doch häufiger macht: Eine Funktionsreferenz rumzugeben und die Funktion in der Hand hat und die einfach nur so aufruft, dann ist auf einmal this undefined, weil es nicht mehr da ist, weil da nichts mehr vor dem Punkt stand. Und dann braucht man sowas wie bind. Mit bind kann man halt über eine Funktion längerfristig ein this dranhängen und sagen: So, an sofort immer, wenn du aufgerufen wirst ist das dein this. Und das ist bei dem bind dann auch so, in der Implementierung könnte ich das jetzt einfach zeigen, aber glaubt mir einfach, dass wenn man bind macht, dann bleibt das halt so. Auch wenn man dann call mit einem anderen Objekt macht, das ändert nichts daran, das ist halt einfach so. Und im Prinzip macht die error function genau das, sie macht call mit den this, was drumherum ist und dadurch kann man halt diesen Effekt mit diesem man iteriert über irgendwas drüber mit einer for-Schleife oder sowas, dann kann man halt, wenn man this sagt, meint man das this, was drumherum da war. Und auf diese Art und Weise funktioniert dieser Pfeil. Also auch der ist keine… Also nichts was du mit Class oder mit dem Pfeil machst heute, konntest du vorher nicht machen. Also alles davon ging schon, es sah nur anders aus. Also üblicherweise hättest du dann früher halt eine function und ein .bind(this) dahinter geschrieben. Das ging, aber ist halt mehr Schreibarbeit und ein bisschen schwieriger zu lesen, aber diese neue Syntax macht das halt viel angenehmer. Und das… Also der Pfeil kommt meines Wissens nach aus CoffeeScript, das war ja auch eine…, also ist immer noch eine Sprache, die zu JavaScript kompiliert und die halt viele von diesen Sachen wie Class und Pfeil und so weiter schon eingeführt hat als Pre-Compiler, der halt quasi das CoffeeScript genommen hat, daraus JavaScript gebaut hat, dann ausgeführt werden konnte. Und der hat genau das gemacht, der hat so einen Pfeil eingeführt und dann hat der das halt verwandelt einfach in eine Funktion, die am Schluss bind aufruft. Und dadurch wird das halt so ein bisschen angenehmer. Da fällt mir auch gerade noch eine Sache ein zu Funktion, was ich tatsächlich auch eine Sache finde, die jetzt jemand dessen Lieblingssprache Ruby ist, also Zweitlieblingssprache, meine Lieblingssprache ist natürlich Halunke, aber meine Lieblingssprache Ruby ist und Ruby eine andere… eigentlich in jedem Aspekt lieber mag als JavaScript. Aber in einem Aspekt mag ich tatsächlich JavaScript lieber und das ist wie Funktionen halt funktionieren. Weil in Ruby gibt es da halt so einen Wildwuchs, du hast irgendwie Methoden, du hast Proc, du hast Lambdas, du hast Blöcke und eigentlich sind das alles Funktionen. Aber in Ruby sind die halt doch alle unterschiedlich und manchmal braucht man das, manchmal braucht man das und manchmal verwandelt man das eine in das andere. Und in JavaScript ist das so schön, dass du eigentlich nur Funktionen hast. Auch Methoden sind einfach nur Funktionen. Und das ist schon ein cooles Konzept, weil das macht viele Sachen einfacher. Und auch andere Programmiersprachen, auch Java beispielsweise wurden dann ja irgendwann Lambdas eingeführt, weil du halt einfach eine Funktion nicht einfach so rumreichen kannst und so weiter und so fort. Und in JavaScript ist das so schön einfach, dass du immer nur Funktionen hast und die sind immer das gleiche. Und das finde ich ein cooles Feature an JavaScript, was ja auch leider halt einige Nachteile dann mit sich gebracht hat, weil es dann halt so aussehen sollte wie bei den anderen Sprachen. Aber das Kernkonzept davon finde ich eigentlich schon sehr cool, dass es halt wirklich ein so ein Ding ist, was ich auch einmal verstehe und dann muss ich es auch nie in etwas anderes umwandeln oder sowas. Wie jetzt bei Ruby, wo ich dann halt so eine Methodenreferenz bekommen kann und was weiß ich, das ist alles ganz blöd. Und das finde ich in JavaScript echt cool.
Robert Glaser:
Ich mache ja auch schon ewig Ruby und bis heute muss ich immer wieder neu überlegen: Brauch ich jetzt ein Lambda, brauche ich jetzt ein Proc, mache ich ein Block auf? Also das ist bescheuert und das finde ich, also fand ich bisher bei JavaScript wirklich derartig gut gelöst und einfach verständlich. Klar, mit dem this Kontext muss, das muss man einmal verinnerlichen, auch sich diese neue Sprachfeature vielleicht einfach mal aneignen, weil es sehr viel klarer macht. Aber im Vergleich zu anderen Sprachen, die ich so kenne, finde ich es auch wahnsinnig verständlich.
Lucas Dohmen:
Und gerade da ist es halt auch so, dieser Pfeil, der sagt mir halt irgendwie das ist eine arrow function oder so, aber das Schöne ist, dass es halt trotzdem eine Funktion ist. Und das ist… verhält sich wie eine function, es ist nichts was jetzt grundlegend anderes ist. Es ist eigentlich eine function, die halt ein bind hat, aber sonst ist es nichts Komisches und das finde ich cool.
Robert Glaser:
Okay. Wie sieht es denn aus, wenn ich jetzt vielleicht mal ein Back-End Projekt starten möchte mit JavaScript? Gibt es da irgendwelche Frameworks, die ich nutzen könnte? Also es gibt mit Sicherheit haufenweise Frameworks, aber gibt es sowas wie Rails, was full-stack-artiges, wo ich schnell alles Mögliche dabeihabe, um möglichst produktiv aus den Hufen zu kommen? Oder muss ich doch sehr viel Architektur und Softwareentscheidungen noch treffen? Also wir haben auch gerade zu dem Thema ORM kurz gesprochen, gibt es so Frameworks in der JavaScript-Welt mittlerweile in 2021?
Lucas Dohmen:
Also ich finde die Antwort ist erstmal: Grundlegend ist die Philosophie von JavaScript eher einzelne Bibliotheken zu haben und die selber zusammenzustecken. Also dieses Baukastensystem ist viel üblicher als irgendein großes Framework. Das haben verschiedene Leute schon versucht Rails nachzubauen, ich erinnere mich noch an Sails beispielsweise, was nicht toll ist. Das wurde immer wieder versucht, aber die Beliebtheit davon ist einfach nicht da gewesen. Also ich glaube viele… Das ist einfach eine andere Philosophie, die dahintersteckt, wodurch viele Leute einfach diesen Library Weg bevorzugen. Aber grundsätzlich… Also ich glaube so der Marktführer mit Abstand im Bereich Webframework ist halt Express und dann kommt erst ganz lange später irgendwas anderes. Das ist schon wirklich so das, was man üblicherweise nimmt und dann gibt es halt auch nochmal irgendwie schnellere Nachbauten davon, was weiß ich. Aber grundsätzlich ist das so das, was man hat und das entspricht halt so Sinatra in Ruby, Flask in Python, keine Ahnung… Also diesen Microframeworks, die eigentlich nur Routing machen und sonst nichts. Und als jemand, der Rails viel entwickelt, vermisst man da einfach Dinge, auf jeden Fall. Also mir würde da einfallen: Reverse Routing, Integration… Also eine ganz, ganz schreckliche Sache ist halt Formhandling, also wenn man Formulare baut und dann möchte man halt irgendwie die Errors wieder reinschleifen können und so weiter, das baust du halt jedes Mal von neu und da gibt es auch keine coolen Lösungen für. Das ist leider wirklich nervig, das fehlt immer noch. Aber ORMs gibt es mittlerweile glaube ich ganz gute. Ich glaube ihr beide habt damit tatsächlich mehr Erfahrung als ich, weil ich meine Node-Projekte hauptsächlich mit Redis im Back-End… also als Datenbank gemacht habe und die, da habe ich dann einfach den Redis-Treiber benutzt und mit Redis rumgeeiert und gar nicht so viel ORM Kram gemacht. Vielleicht könnt ihr das dann nochmal ergänzen?
Robert Glaser:
Mit sowas Ordinärem wie einer relationalen Datenbank gibst du dich ja gar nicht ab.
Lucas Dohmen:
Genau.
Robert Glaser:
Aber Lisa, hast du schon mal einen ORM benutzt in JavaScript?
Lisa Moritz:
Ja, genau. Also ich hatte in einem Projekt mit einer postgres im Hintergrund gearbeitet und hatte dann dementsprechend dafür einen Mapper benutzt und in einem Projekt, wo ich mit dem Lucas auch zusammen war, hatten wir eine mongodb im Hintergrund laufen und da hatten wir natürlich auch so ein ORM im Einsatz. Mit der postgres weiß ich noch, da hatten wir auch noch so eine history Geschichte miteingebaut, also dass die Datenbankhistorie immer nachgezogen wird, wenn irgendwelche neuen Tabellen und so weiter dazukamen. Also das kann man halt nicht nur in Java umsetzen, sondern eben auch in JavaScript, was viele nicht glauben. Was ich immer noch super wichtig zu erwähnen finde, wenn es um irgendwelche Frameworks geht: Ich glaube viele Leute denken nicht daran, dass man auch im JavaScript Back-End mit Translation Keys und so weiter arbeiten kann. Also ich kann auch supereinfach Internationalisierung meiner Websites Back-End gestalten. Ich weiß immer den Namen von dem Framework nicht, was ich jetzt bestimmt schon 5–6-mal verwendet habe, aber immer vergesse ich den Namen. Aber das ist halt super. Man gibt ganz klassisch Key Value pairs an, man kann eben auch Platzhalter einfügen und das ist einfach… Also man braucht das oft, gerade wenn man irgendwie im Back-End Bereich schon rendert, mit irgendwelchen Templating Engines agiert, wie pug zum Beispiel, das mag ich ganz gerne. Und das wird oft vergessen und ist eigentlich eins der wichtigsten Dinge, die man immer im Projekt dabeihaben sollte.
Robert Glaser:
Also wir können uns schon so alles zusammenstecken, was wir so brauchen, um eben eine Back-End Anwendung zu bauen. Lucas, du hattest gesagt: Express und andere Frameworks sind eigentlich nicht viel mehr als HTTP-Abstraktionen und übernehmen so ein bisschen das Routing. Aber wenn meine URL eben dann richtig gerouted ist, da treffen die dann… hören die dann auf. Dann treffen die keine Aussagen mehr: Was passiert jetzt hier an der Stelle. Die typische Controller-Stelle, wie man das so kennt des MVC-Frameworks. Da war ich am Anfang so ein bisschen verdutzt und auch genervt, weil dann musste ich wieder Technologieentscheidungen treffen. Ich wollte einfach nur produktiv sein, dann musste ich mir überlegen: Womit will ich denn jetzt meine Templates rendern? Womit will ich meine Datenbank-Queries machen? Da habe ich viel suchen müssen, dann habe ich zwei Dinge ausprobiert als ORM, und bin dann bei Sequelize gelandet. Fand den auch sehr gut, habe darüber async/await kennengelernt und dann wollte ich meine magische Tabelle rendern, die die Datenbankrecords in HTML darstellt und hatte wieder nichts zur Hand. Und dann musste ich wieder suchen, was nehme ich jetzt? Nehme ich pug? Nehme ich etwas ganz anderes? Das fand ich persönlich extrem nervig. Würdet ihr sagen, ihr seht das genauso? Oder würdet ihr sogar soweit gehen und sagen, dass dieses Umfeld weniger Produktivität, gerade zu Anfang, ermöglicht als andere Ökosysteme wie Ruby, Java, was es alles sonst noch gibt?
Lisa Moritz:
Ich hatte eher das Gefühlt, dass ich das eher positiv finde als negativ, dass ich nicht schon mit irgendwelchen Dingen vorkonfrontiert werde. Also gerade was Templating Engine angeht gibt es ja solche und solche, die Spaß machen beim Schreiben und die die man in die Tonne werfen möchte, wenn man irgendwie zwei Zeilen geschrieben hat. Und gerade dadurch, dass man eben so ganz leichtgewichtige Dinge wie pug einfach einbinden kann, wenn man das sagt, dass reicht einem jetzt und nicht eben die dahergekommene Sprache XY verwenden muss, also mir ist das jetzt… aktuell bin ich leider nicht in einem JavaScript.Projekt, sondern in einem Java-Projekt. Und ich muss gestehen, ich habe jetzt wirklich lange fast nur pug gemacht an Templating Sprachen und jetzt mach ich Thymeleaf. Und ich muss gestehen, ich finde das gar nicht so toll wie man denken könnte. Und wir haben da aber gar keine andere Möglichkeit und das finde ich total schade, weil wenn man jetzt im Node-Umfeld wäre, könnte man vielleicht noch schauen: Sind meine Dinge überhaupt kompliziert genug, um diese Templating Sprache, die gerade so super viel kann, zu verwenden? Oder könnte ich die jetzt vielleicht einfach austauschen? Also ich finde halt gerade das ist ja eine Stärke, dass du dir die Dinge schnappen kannst, die zu dir gerade an besten passen. Oder sagen wir du hast jetzt nur mit, ich glaube Handlebars gibt es auch im JavaScript. Du hast jetzt nur damit gearbeitet und du müsstest dich bei allen anderen einarbeiten, dann kannst du dir jetzt einfach Handlebars schnappen. Statt eben pug, weil du pug gerade blöd findest. Also ich finde das eigentlich ziemlich, ziemlich gut, dass man eben diese freie Wahl hat und sich nicht in irgendwas festlaufen muss.
Robert Glaser:
Okay, das wird mit Sicherheit aber auch persönlicher, von persönlicher Vorliebe geprägt. Einige treffen diese Technologieentscheidungen wahrscheinlich lieber, andere, wie ich, weniger. Aber wenn ich ein großes Team habe oder mehrere Teams, die sich darauf einigen müssen, da habe ich schon wahrscheinlich zu Anfang ein bisschen ein Entscheidungs-Overhead, oder, Lucas?
Lucas Dohmen:
Auf jeden Fall. Also das ist halt ein Trade-off. Du hast die beliebige Sache, die du entscheiden kannst. Was cool ist, wenn du dann halt dir das raussuchen kannst, was du am liebsten magst. Aber wenn du halt in dem Team von fünf Leuten oder sechs Leuten dir da den Stack zusammenschrauben willst, dann kann halt schon mal die ein oder andere Woche ins Land gehen, bis man halt alle Kämpfe ausgekämpft hat, sag ich mal. Und als Consultant ist es auf jeden Fall auch ein kleiner Nachteil, wenn du halt in einem Projekt… oder vielleicht auch ein bisschen größerer Nachteil, wenn du halt in ein Projekt reinkommst, was du nicht kennst, dann musst du halt erstmal schauen, welche Entscheidungen wurden getroffen? Und so weiter. Wenn ich in ein Rails-Projekt reinkomme, bin ich am Tag 1… weiß ich direkt, wo alles liegt, ich weiß direkt wie ich eine Datenbank-Query mache, ich weiß direkt wie ich einen Test schreibe und so weiter und so fort. Und bei JavaScript gibt es halt, also ich kenne alleine irgendwie aus 10 Projekten 10 verschieden Testframeworks und das ist nicht übertrieben, das ist so. Und dann muss man halt immer erstmal gucken: Wie geht in diesem Testframework jetzt Mocking? Wie geht in diesem Testframework dies? Wie geht in diesem Testframework das? Und dann, was haben sie denn jetzt benutzt, um ihren Body zu parsen? Was haben sie benutzt, um ihre Cookies abzulegen? Und so weiter und so fort. Und dann bist du halt oft doch ein bisschen am forschen und führt auch manchmal dazu, dass in einem Projekt für das gleiche Ding drei Libraries eingebunden sind, weil das eine war die Dependency davon und dann hat aber der eine noch gesagt: Ich finde das aber cooler als das. Und darum habe ich das noch eingebunden. Und das führt halt manchmal zu einem Wildwuchs und das ist auf jeden Fall auch ein Nachteil, wenn man da halt einsteigt. Aber ich gebe der Lisa Recht, du kannst dir halt einen coolen Stack zusammenbauen, aber das ist halt ein Trade-off. Du kannst… Ich glaube es hat beiden seine Vor- und Nachteile. Ich persönlich finde halt diesen Ansatz so, es gibt halt irgendwelche Defaults, du kannst die aber relativ gut ersetzen. Finde ich persönlich einen ganz guten Ansatz. Wie es jetzt bei Rails beispielsweise ist, wo mal grundlegend viele Sachen entschieden sind. Aber wenn ich jetzt zum Beispiel dieses Ding, was irgendwie Datenbankeinträge erzeugt doof finde, dann kann ich halt ein anderes Ding nehmen, was Datenbankeinträge erzeugen kann für meine Tests. Das finde ich persönlich einen ganz coolen Ansatz, aber das ist halt dadurch, dass das Node- und… also das JavaScript- und auch das gerade das Node-Ökosystem wirklich riesig sind und für alles unglaublich viele Auswahlmöglichkeiten sind, ist das manchmal ein bisschen schwierig und ich finde es auch schwierig manchmal dann eine gute Library in dem Bereich zu finden. Aber wie Lisa schon sagte, wenn man einmal so seine go-to Tools hat, Lisa hat die Translation Library, die sie immer benutzt beispielsweise oder halt irgendwie Express oder was auch immer und dann weiß man im nächsten Projekt, diese Sachen kann ich wieder zusammenstecken, dann ist es eigentlich gar nicht mehr so wild. Aber wenn man dann irgendwie sagt so: Hey, jetzt brauche ich aber noch irgendwas um… keine Ahnung, mir fällt jetzt kein gutes Beispiel ein. Dann muss man halt wieder anfangen zu suchen, dann greift man vielleicht auch mal auf Kollegen und Kolleginnen zurück, um dann nachzufragen: Habt ihr da schon mal was benutzt? Das ist halt wie gesagt, ich würde sagen ein Vor- und Nachteil.
Robert Glaser:
Bekanntes Problem auch: Man braucht eine Template Library, hat drei ausprobiert, sich dann auf eine geeinigt und zwei vergessen die Dependencies zu entfernen. Das kann eben auch passieren.
Lucas Dohmen:
Ja.
Robert Glaser:
Okay. Kommen wir doch nochmal zum Entwicklungsalltag zurück. Ich bin ja jemand, der probiert gerne mal eben was aus, bevor ich irgendwie große Funktionen schreibe. Bin so eine REPL-artige Entwicklung gewohnt von da wo ich herkomme. Und das fand ich bisher immer ganz angenehm. Geht sowas auch in JavaScript? Und vielleicht als Folgefrage dazu: Wie debugge ich denn überhaupt? Also zu dem Zeitpunkt, wo ich das kennengelernt habe, fand ich die REPL um einfach mal schnell Dinge irgendwie auszuprobieren so ein bisschen holzig. Ich kann nicht mehr genau artikulieren warum. Und ich fand das Debugging weird, weil ich musste auf einmal einen Chrome Browser starten, obwohl ich eigentlich eine Back-End Anwendung programmiert habe und dann ging irgendwie ein Debugger in meiner Chrome Konsole auf, der mir meinen Back-End Code dann an der Stelle angehalten hat. Das fand ich irgendwie recht komisch integriert. Ist das heute noch so und wie sind da eure Erfahrungen?
Lisa Moritz:
Also REPL-mäßig, es gibt halt die Node-Konsole. Ich gebe zu, ich nutzte die nicht so oft, wenn ich irgendwas ausprobiere, mache ich mir eigentlich immer schnell einen Browser auf und tippe das da ein. Klar, kann ich da keine Datenbank-Geschichten irgendwie prüfen, sondern habe dann einfach JavaScript zur Verfügung, das mache ich am häufigsten. Debugging, ich nutzte momentan Visual Code zum Programmieren von JavaScript und da ist ein Debugger inklusive, wahrscheinlich nutzt das auch irgendwie Chrome im Hintergrund oder so. Aber auf jeden Fall geht das mittlerweile deutlich einfacher. Aber ich habe das Gefühl, dass man bei Java häufiger wirklich einen Debugger braucht als bei JavaScript. Aber das kann auch ein Gefühl sein. Also ich brauche den bei JavaScript deutlich seltener als ich den bei Java gebraucht habe.
Robert Glaser:
Lucas, wie sieht das bei dir aus?
Lucas Dohmen:
Ich bin ja so ein Konsolenmensch, der sein ganzes Leben im Terminal verbringt
und da auch seinen Editor hat und so weiter. Und ich habe eigentlich sehr… also
mein Hauptding ist immer noch eigentlich irgendwelche Sachen zu loggen und dann
zu gucken, ob das das ist, was ich möchte. Das ist… Ich weiß, dass das irgendwie
Steinzeitmenschenmäßig ist, aber ich mag das einfach am liebsten, das hilft mir
oft die Sachen so zu finden, wie ich sie brauche und auch mehrere Sachen
hintereinander zu finden. Und das mache ich sowohl in Ruby als auch in
JavaScript so als Hauptding, ab und zu benutzt ich dann doch einen Debugger in
beiden Sprachen. Und wie du sagst, man hat halt irgendwie so ein bisschen diesen
Tooling-Bruch, weil man dann halt irgendwie seinen Browser aufmacht, um das zu
machen, hat aber auch den Vorteil, dass dieser Debugger, der in Chrome eingebaut
ist, einfach wirklich cool ist. Also man kann dann halt in den Scope reinschauen
und so weiter. Mittlerweile, wie Lisa sagt, wenn man halt sowas wie Visual
Studio Code benutzt, ist das dann halt der selber, der da drin ist, also aus dem
Browser ausgeflanscht und da drin und dann ist das halt tatsächlich in deinem
Editor. Und wenn man das gerne mag, ist das glaube ich mittlerweile richtig
cool, dadurch, dass das einfach da mit integriert ist. Wenn man wie ich lieber
in der Konsole arbeitet, wenn ich jetzt in Ruby das mache, dann geht da einfach
in der Konsole einfach so ein Debugger auf, wo ich dann halt eine REPL habe, die
an den Punkt einsetzt, wo ich gerade bin. Das habe ich bisher in JavaScript
nicht gefunden, wie das geht. Da geht dann… Also da mache ich dann trotzdem
irgendwie den Chrome auf, was nicht so richtig gut zu meinem persönlichen
Workflow passt. Aber ich glaube, wenn man tatsächlich eher mit diesem… Also ich
meine Visual Studio Code hat sich ja schon ein bisschen so zum Standard der
JavaScript Entwicklern/Entwicklerinnen glaube ich entwickelt, da drin ist das
glaube ich ziemlich cool mittlerweile. Und macht auch gar nicht mehr so
Umstände, kannst dann direkt irgendwelche Breakpoints anklicken im Editor und
dann macht er halt da einen Breakpoint hin und so weiter, was früher halt nicht
so ging. Ich mache das halt immer noch, indem ich da einfach in die Zeile
debugger
hinschreibe, dann geht auch der Debugger an der Stelle auf, aber das
macht schlussendlich der Punkt, den man da setzt, auch. Aber wenn man das halt
gewohnt ist, dann ist das sicherlich die coolere Experience und ich glaube, dass
lohnt sich das anzuschauen. Also wenn man diese Art der Entwicklung mag, würde
ich auf jeden Fall Visual Studio Code ans Herz legen, weil das löst das einfach
cool. Alles Sachen, die man dafür braucht sind vorinstalliert, man muss nicht
noch irgendwelche Plug-Ins zusammensammeln und so. Und ja, ich glaube das ist
eine coole Lösung dafür.
Robert Glaser:
Jetzt weiß ich auch wieder was ich holzig fand an dem Debugging. Ich bin es nämlich auch gewohnt, dass ich ein Entwicklungsserver laufen habe, einen lokalen, setzte dann dagegen ein Request ab oder was auch immer, dann rotiert ein Log durch und ich habe an die Stelle, wo ich erwarte, dass er jetzt stoppt ein Breakpoint gesetzt, aber dann passiert da nichts, sondern da geht ein Chrome auf. Das musste ich erstmal verinnerlichen. Das fand ich, wie du wahrscheinlich auch einfach weird, aber man kann sich dran gewöhnen. Und wie Lisa sagte: Es gibt ja moderne Alternativen, wie zum Beispiel die Integration in VS Code, die das ein bisschen einfacher macht. Wo lasse ich denn mein JavaScript, wenn ich es lokal entwickele, denn überhaupt laufen? Also es gibt ja Node.js, das kennen wahrscheinlich alle Hörerinnen und Hörer oder haben es zumindest schonmal gehört. Gibt es da auch neuere Alternativen dazu?
Lucas Dohmen:
Ja, also ich würde sagen, wenn… Also von dem, was man so allgemein hat, sieht man immer noch Node. Das ist einfach das… Das ist der am weitesten verbreiteste Ding, da gibt es die ganzen Bibliotheken für und so weiter. Aber relativ neu ist halt Deno, das ist von demselben Meschen initialisiert der auch Node.js angefangen hat, nämlich Ryan Dahl, der hat damals Node erfunden und der hat halt vor, ich weiß nicht mehr 2 Jahren oder 3 Jahren, einen Vortrag auf einer großen JavaScript Konferenz gehalten, wo er halt gesagt hat: Das sind die 10 Dinge, die ich an Node.js bereue, die ich heute anders machen würde als ich sie damals gemacht habe. Und das hat er dann am Schluss gesagt: So und weil ich die Sachen bereue mache ich jetzt ein neues Projekt und das heißt Deno. Dazu muss man sagen, dass Ryan Dahl aus dem Node.js Tagesgeschäft schon seit vielen Jahren raus ist, also der hat das schon an andere Leute übergeben. Das heißt also die Entwicklung von Node.js tangiert das überhaupt nicht, das geht genauso weiter, wie vorher, da sitzen genauso viele Leute hinter. Also man muss sich jetzt keine Sorgen machen, dass das irgendwie das neue Node ist und man muss sein Node wegwerfen. Also keine Sorge, das geht genauso weiter und da wird bestimmt auch der Speed nicht abnehmen in der Entwicklungszeit. Aber Deno ist auf jeden Fall trotzdem interessant, Deno ist gerade vor allem vor Leute interessant, die gerne TypeScript mögen, weil Deno halt per Default TypeScript ausführen kann. Also man schreibt einfach seine Dateien als TypeScript Datei und sagt hier Deno: ausführen. Und dann macht der die Konvertierung zu JavaScript intern und man merkt davon gar nichts. Wenn man halt irgendwie eine Back-End Anwendung mit TypeScript baut, ist das immer so ein bisschen awkward mit Node.js. Da muss man halt irgendwie… hat man irgendwie eine Dateistruktur und dann sagt man so: Kompiliere das mal bitte in diesen Ordner daneben. Den führ ich dann aus. Was irgendwie ein bisschen blöd ist immer, aber das ist halt bei Deno ein bisschen angenehmer, weil es halt einfach so nativ drin ist. Sonst hat es halt einige interessante Entscheidungen, wie beispielsweise es gibt nicht sowas wie eine Dependency File, wo alle Dependencies drinstehen, also in Node wäre das jetzt die package.json, wo alle Dependencies drinstehen, sondern man schreibt direkt im Import Statement einfach direkt den Pfad zu der URL, wo man diese Sache herholen will und der lädt das dann im Hintergrund runter und führt das aus und so weiter. Interessante Entscheidung, die halt einfach anders funktionieren, als sie das bei Node.js tun, weil er das halt heute anders machen würde als er das tut. Genau, und deswegen ist Deno auf jeden Fall einen Blick wert, ob ich das heute jetzt produktiv in einem Kundenprojekt einsetzten würde, weiß ich nicht. Vielleicht noch ein bisschen früh, aber es ist auf jeden Fall interessant sich das mal anzuschauen und auch mal zu schauen, was es da alles gibt. Aber es hat auf jeden Fall den Nachteil, dass es dafür viel weniger Libraries gibt und dann natürlich auch Sachen fehlen werden, die man dann vielleicht selber bauen muss. Ist aber vielleicht auch eine Chance coole neue Libraries zu entwickeln, die vielleicht auch aus den Fehlern gelernt haben, die man in Node gemacht hat. Das ist wieder ein Trade-off.
Robert Glaser:
So, das war jetzt eine kurze Reise durch JavaScript. Ich glaube, Lucas, du hast ja gerade noch package management erwähnt, das könnte man jetzt noch beliebig vertiefen. Lohnt aber da vermutlich eine eigene Folge zu machen, genauso wie vielleicht in ein paar Monaten mal zu Deno. Lisa, ich glaube die Frage dürfen wir uns auch mal erlauben. Ich hatte zu Anfang gesagt, ihr seid ja beide Trainerinnen und Trainer unserer JavaScript-Schulung, was lerne ich denn da?
Lisa Moritz:
Also in der JavaScript-Schulung, wir haben sie genannt ‚JavaScript verstehen und anwenden‘, lernt man vor allen Dingen mit JavaScript richtig umzugehen. Weil die meisten Leute, die irgendwie JavaScript programmieren heutzutage, die haben JavaScript nicht von der Pike auf gelernt, sondern die kommen von anderen Sprachen, wie zum Beispiel Java und müssen jetzt auf einmal JavaScript schreiben. Und wir sind ja vorhin schon auf die prototypische Vererbungskette eingegangen oder auch auf this und es gibt da so ein paar, ja, Quirks hast du das so nett mal genannt, die die Sprache irgendwie schwierig machen. Aber sie ist ja eigentlich wirklich schön. Und in diesem Training gehen wir auf eben genau diese Grundkonzepte der Sprache ein, auch auf ein paar weiterführende Konzepte und das Coole ist, wir haben einen… so ein praktisches Beispiel, was wir durch die ganze Schulung ziehen und anhand dessen wir dann die Konzepte erklären oder erzählen. Und man baut sowohl Back-End seitiges JavaScript als auch Front-End.
Robert Glaser:
Okay, cool. Hätte ich vielleicht mal besuchen sollen, hätte es die schon gegeben vor ein paar Jahren. Schön, dass ihr da wart. Wir sind jetzt glaube ich am Ende unserer kurzen Reise. Vielleicht sehen wir uns in zukünftigen Folgen zu ein paar Spezialthemen nochmal wieder, ich habe mich sehr gefreut mit euch darüber zu quatschen. Und wünsche euch und allen Hörerinnen und Hörern einen guten Start in dieses neue Jahr! Bis bald! Tschüss!
Lucas Dohmen:
Bis dann! Ciao!
Lisa Moritz:
Tschüss!