Sie sind hier : sebastian1012.bplaced.net/ homepage-neu / neuigkeiten / Entwickler-Blog.php

https://entwickler.de/feed/rss2

Der Scrum Master: Gelebte Agilität daheim (15.08.2019 07:54:50)

Wenn Agilität ein Mindset und keine Methode ist, macht sie auch vor dem eigenen Zuhause nicht halt Die heimische Anwendung agiler Ideen birgt jedoch ganz eigene Herausforderungen, wie Jürgen Knuplesch im 12 Teil seiner sehr realen und doch erfundenen Geschichte des Scrum Masters aufzeigt

Wir hatten es ja schon öfter davon, dass die agile Arbeitsweise ein Mindset und keine Methode oder gar ein Prozess ist Oder vielleicht doch nicht? ?Mindset? ist ja so ein neudeutsches Wort und müsste wohl mit ?innerer Einstellung? übersetzt werden Das hat einen entscheidenden Vorteil und einen entscheidenden Nachteil Der Nachteil ist: Wenn jemand diese Einstellung nicht hat, nicht haben will oder nicht teilt, dann helfen alle agilen Methoden, alle Retrospektiven, alle agilen Tools nichts oder nur wenig

Agilität kommt von innen

Du kannst einen Menschen nicht zwingen, agil zu denken und zu handeln, wenn er das Mindset nicht teilt Und jemanden zu zwingen ist ja ein agiles Antipattern, das die Motivation nachhaltig zerstört Du kannst geduldig versuchen zu überzeugen und warten, bis deine agilen Funken im anderen ein Feuer entfachen Menschen, die sich aktiv dagegen wehren, die dir nicht zuhören, werden lange bis ewig brauchen, um zu verstehen, dass sie selbst die größten Gewinner eines agilen Mindsets wären, wenn sie es annehmen würden Der Respekt vor der anderen Person hindert den Scrum Master daran etwas zu erzwingen, weil er weiß, dass es vom anderen kommen muss Sonst wird es nicht funktionieren ?Man kann den Hund nicht zum Jagen tragen?, pflegte meine Mama zu sagen und das gilt auch für das agile Mindset Lustigerweise sind viele, die lauthals ?agil? ablehnen, bei genauerem Hinsehen agiler als manche, die sich als agile Evangelisten ausgeben Erstere sind mir sogar deutlich lieber als Letztere Agil ist ja auch nicht jemand der mit agilen Fachbegriffen um sich wirft, sondern der selbstorganisiert, menschengerecht effizient und flexibel handelt und denkt, jemand der die agilen Prinzipien anwendet egal ob er sie kennt oder nicht

Mehr vom Scrum Master

Alle Teile der Fortsetzungsgeschichte „Der Scrum Master“:

  • Teil 1: Wie alles begann
  • Teil 2: Die Offenbarung
  • Teil 3: Wiedereintritt in die Realität
  • Teil 4: Das potentiell nicht auslieferbare Produktinkrement
  • Teil 5: Spannung im Meeting
  • Teil 6: Konstruktive Konfliktbewältigung im agilen Setting
  • Teil 7: Eine Weihnachts-Scrum-Geschichte mit Kudo
  • Teil 8: Hey Du ? mit Selbstreflexion ans Ziel
  • Teil 9: Ist Agile tot?
  • Teil 10: Agiler ohne Scrum
  • Teil 11: Agilität braucht Mitbestimmung
  • Teil 12: Agil daheim

Das Gute daran, dass Agilität ein Mindset ist, ist, dass jemand der dieses Mindset angenommen hat, gar nicht anders kann, als agil zu denken und zu handeln Auch in einem Wasserfallprojekt wird er oder sie agil handeln, auch wenn er nicht alle Rahmenbedingungen ändern kann, denn Realitätssinn gehört ja auch zum agilen Mindset Und das hört auch nicht in dem Moment auf, wenn er die Bürotür schließt und nach Hause geht Ein agiles Mindset hat man oder man hat es nicht bzw entwickelt es

Zu Hause beim Scrum Master

Zu Hause stand bei uns ein großes Familienfest an In einer Familie mit drei Kindern bedeutet das viel Arbeit Meine liebe Frau nahm wie immer die Zügel in die Hand und ich hatte mir zwei Tage Urlaub genommen Die Kids hatten Ferien, aber keine große Lust, sich an der Arbeit selbstorganisiert zu beteiligen Das agile Mindset hatte bei ihnen noch nicht vollständig gezündet und ich war inzwischen auch bereit das zu respektieren, wobei dies bei den eigenen Kindern noch etwas schwerer fällt als bei den Kollegen bei der Arbeit Aber auch daheim funktioniert das ?Push?-Prinzip nicht wirklich, aber zum ?Pull? war es halt auch noch nicht gekommen Meine Frau wiederholte bereits am Morgen gebetsmühlenartig, dass sie so viel zu tun hätte und man ihr doch helfen solle Da ich aber zu Hause auch manchmal sehr unagil die Arbeit nicht sehe und es kein Backlog gibt, in dem ich nachschauen kann, wusste ich auch nicht so recht, was ich tun könnte Zudem meldet sich daheim gerne auch mein Freund, der innere Schweinehund, der meint es wäre nun Zeit mich auszuruhen und zu chillen Das ist natürlich kurz vor einem großen, von uns veranstalteten Familienevent fatal So ein bisschen widerspreche ich damit natürlich dem oben Gesagten, denn man kann sein Mindset auch manchmal von ?agiler Einstellung? auf ?jetzt schalte ich mal komplett ab und ignoriere was zu tun wäre? umschalten Genau genommen ist es aber auch agil, wenn man sich zwischendurch einmal Ruhe gönnt, denn sonst geht dem Menschen auch die Kraft aus

Die Situation eskaliert

Es ist menschengerecht, dass wir Ruhe und Entspannung brauchen, um wieder in Höchstform zu kommen In diesem Fall war es insgesamt aber wenig hilfreich, denn meine Frau stand kurz vor einem Nervenzusammenbruch: ?Kann mir mal jemand was helfen? Es ist noch so viel zu erledigen Putzen, Kochen, einkaufen, das Silberbesteck muss poliert werden und noch viel, viel mehr? ?Ja, wenn du mal genau sagen könntest, was zu tun ist! Dann könnte ich dir auch helfen!? Inzwischen war ich auch etwas sauer geworden und fühlte mich persönlich angegriffen und abgewertet Oh ja: Die Gefühle Sie sind ein wesentliches Ausstattungsmerkmal des Menschen, das viel zu wenig Beachtung und Fürsorge empfängt Stattdessen setzen wir den Verstand über alles und versuchen auf der Sachebene zu bleiben und komplexe Abläufe, wie Firmen und Familien zu rationalisieren, was bei deren Komplexität zum Scheitern verurteilt ist Um es kurz zu machen: Der Streit und die Emotionen eskalierten und weder ich noch sonst wer in der Familie hatte sich dabei mit lösungsorientierten Vorschlägen hervorgetan Was aber meist bei einem Familienstreit passiert, ist die ?Ruhe nach dem Sturm? Alle fünf Familienmitglieder saßen bedröppelt allein in einem Zimmer und wohl jeder überlegte, wie wir aus dieser Sackgasse wieder herauskommen könnten Einer von den Fünfen war ich

Angewandte Agilität in der Familie

?Mhmmm?, dachte ich, ?da war doch was? Schritt 1 musste sein, dass ich zugab, dass ich überreagiert und dem anderen unnötigerweise Vorwürfe gemacht habe Das war der erste Schritt zurück Weg von der Suche nach dem Schuldigen, hin zu einer Lösung der Herausforderungen Und Schritt 2 wäre dann ein Lösungsvorschlag, durch den wir den komplexen Prozess der Vorbereitung auf ein großes Familienfest besser managen können Und auch da fiel mir sofort ein erster Schritt ein: Wir machen unsere Küchentür zum Kanban Board Genau: Unser Product Owner ist meine Frau, denn sie hat alle Aufgaben bereits im Kopf Wenn ich sie nur dazu bringe alles aufzuschreiben, dann kann jeder sich eine Aufgabe nach der anderen greifen und umsetzen Zudem kann sie sich dann auf die Aufgaben konzentrieren, die keiner von uns erledigen kann Gesagt, getan Das mit dem auf den anderen zugehen und sagen, dass es mir leidtat, war der schwerere Teil der Übung Aber nach einer Weile waren wir wieder auf einem konstruktiven Kurs zur Erfüllung der Aufgabe Die Idee mit dem Kanban Board wurde zuerst etwas belächelt, aber am Ende fanden es alle ganz gut, auch wenn nicht alle Aufgaben ohne etwas nicht ganz so agilen Nachdruck ihren Abnehmer fanden Auf jeden Fall gelang es unserem Team, die Vorbereitungen gemeinsam zu rocken und das Familienfest am nächsten Tag war ein voller Erfolg Das agile Mindset und auch ein paar agile Methoden machen eben auch vor der eigenen Haustür nicht Halt

Der Beitrag Der Scrum Master: Gelebte Agilität daheim ist auf entwicklerde erschienen


Arbeitsschutz in der IT: Konkrete Probleme und praktische Lösungen (14.08.2019 15:57:32)

Entwickler sind für Unternehmen ein wertvolles Gut, es egibt also Sinn, sie entsprechend zu behandeln Leider nehmen es viele Arbeitgeber nicht ganz so genau beim Thema "Arbeitsschutz" Was angestellte Coder selbst tun können, um für ihre Gesundheit zu sorgen und welche Rolle Technische Schulden mit Arbeitsschutz zu tun haben, erklärt Roland Golla, PHP-Trainer und Consultant, in unserem Interview

Entwickler: Hallo Roland und danke, dass du dir die Zeit genommen hast Beim Thema Arbeitsschutz denkt man zunächst einmal an Helme, Stahlkappenstiefel und feuerfeste Handschuhe ? alles Dinge, die ein Entwickler nicht unbedingt gebrauchen kann, um sicherer zu arbeiten Was genau bedeutet „Arbeitsschutz“ denn im IT-Umfeld, bzw welche Probleme können entstehen?

Roland Golla: Das Problem ist, dass in der Softwareentwicklung viel zu oft unnötiger Druck herrscht, der sich im Projektverlauf immer weiter steigert ? und das macht auf Dauer krank Die Gründe dafür sind vielfältig: schlechte Planung, schlechte Kommunikation etc Und das Problem wird umso größer, wenn Arbeitgeber ihre Entwickler nicht ausreichend weiterbilden und diese nicht einmal ihre eigenen Prozesse optimieren dürfen Dadurch müssen sie auf der Zielgeraden meist wahre Heldentaten vollbringen, um Projekte zu retten, was jedes Mal unendlich viel Energie kostet Tja, und wenn dann alle zwei Wochen Releases anstehen, darf man sich nicht wundern, wenn die Leute irgendwann aus den Latschen kippen Arbeitsschutz in der IT bedeutet also, bessere Strukturen zu schaffen, die genau das verhindern

Entwickler: Es gibt also durchaus körperliche und psychische Belastungen, die bekämpft und gelindert werden müssen Welche Optionen haben Entwickler selbst, welche Möglichkeiten hat der Arbeitgeber, um dem Arbeitsschutz Genüge zu tun?

Entwickler sollten lernen, einfach mal NEIN zu sagen

Roland Golla: Entwickler sollten stärker in sich hineinhorchen und sich fragen, woher denn beispielsweise diese Kopfschmerzen kommen, die sie nun schon seit Wochen haben … Das sind nicht selten Anzeichen für eine anhaltende Überlastung, die in einem schleichenden Prozess schwere gesundheitliche Schäden nach sich ziehen kann: Nervenzusammenbrüche, Burnout etc Ganz zu schweigen von den sozialen Kollateralschäden, wenn Entwickler abends oder nachts zu Hause weiterarbeiten, um in Verzug geratene Projekte wieder in die Spur zu bringen Das belastet dann obendrein das Privatleben und gegebenenfalls die Familie Daher sollten sie lernen, einfach mal NEIN zu sagen Dann werden Dinge eben mal nicht rechtzeitig fertig Heißt: Es darf nicht weiterhin so sein, dass Entwickler mit ihrer Gesundheit dafür bezahlen, wenn sich ihre Arbeitgeber von Kunden im Preis drücken lassen und in Projekten zu gering angesetzte Budgets durch ein unmenschliches Tempo und unrealistische Deadlines wettmachen wollen

Entwickler: Welche Rolle spielen Technische Schulden in dem Zusammenhang und wer muss sie am Ende bezahlen?

Roland Golla: Die Technischen Schulden sind ein großes Problem, und dieses wächst weiter an, wenn in der Softwareentwicklung auch in Zukunft überwiegend auf Stunden- und Honorarbasis gearbeitet wird Das ist ein Teufelskreis, und die Leidtragenden sind die Entwickler Leider fehlt es ihnen hier auch an Know-how für Tests, und wenn sie Tests als nützliches Werkzeug sehen würden, also als Tool, dann würden sie diese auch häufiger einsetzen Dafür brauchen Entwickler aber kreative Freiräume ? doch daran mangelt es leider bei vielen Arbeitgebern Kurzum, es wird wieder einmal am falschen Ende gespart

Entwickler: Mancher Arbeitgeber wird trotz allem keine Notwendigkeit darin sehen, für mehr Arbeitsschutz im Entwickler-Team zu sorgen Wie wirkt sich mangelnder Arbeitsschutz auf Softwareprojekte aus? Warum also lohnt es sich für den Manager, seine Entwickler zu schützen?

Roland Golla: Weil sie sonst abhauen Im Markt herrscht viel Bewegung, und jeder zweite Entwickler hat in den vergangenen Jahren den Arbeitgeber gewechselt Insofern tun Unternehmen gut daran, für optimale Arbeitsbedingungen bzw mehr Arbeitsschutz im IT-Bereich zu sorgen Das steht für Entwickler bei der Wahl des Arbeitgebers heute ganz klar im Fokus Denn einerseits schützt das ihre Gesundheit, und andererseits ist es eine unabdingbare Voraussetzung für effiziente Projektverläufe und eine hohe Softwarequalität Auch darauf legen Entwickler immer größeren Wert Letztlich geht es also um die Machbarkeit von Softwareprojekten Sonst schleichen sich beispielsweise mehr und mehr Bugs ein, was im Nachgang wiederum von den Entwicklern ausgebadet werden muss Und dies, wie gesagt, unter viel zu hohem Energieaufwand und bei entsprechenden, schlimmstenfalls lange anhaltenden Folgen

Entwickler: Wird das Thema Arbeitsschutz in der IT in den kommenden Jahren mehr an Bedeutung gewinnen?

Roland Golla: Auf jeden Fall Der Markt ist sensibilisiert, da Themen wie ?Seelische Gesundheit?, ?Work-Life-Balance? und ?Nachhaltigkeit? mittlerweile sehr ernst genommen werden Die Menschen wollen zufriedener sein, mehr von ihrem Leben haben, gesund sein, aktiv sein, und insgesamt spielt Freizeit spielt wieder eine sehr viel größere Rolle Da passt es natürlich nicht, wenn du als Entwickler den ganzen Tag lang immer nur Tickets von vorne nach hinten ballerst und die ganze Zeit über voll am Limit bist Oder eben dauerhaft drüber, was logischerweise noch weitaus schlimmer ist

Entwickler: Wie erkenne ich als Entwickler, vielleicht trotz Tunnelblick und Scheuklappen, dass ich Hilfe benötige und mein Arbeitsumfeld gefährlich ist?

Manager sollten ihre Entwickler schützen, weil sie sonst abhauen

Roland Golla: In erster Linie daran, dass man immer weniger am eigentlichen Leben teilnimmt, weil sich alles nur noch um die Arbeit dreht Und man auch Sorgen und Ängste, dass Dinge nicht funktionieren, gedanklich mit nach Hause nimmt Das powert einen allmählich mehr und mehr aus, und mit der Zeit treten dann typische Folgen wie Kopfschmerzen, ständige Müdigkeit und depressive Schübe auf Das Tückische daran ist, dass es ein schleichender Prozess ist Umso wichtiger ist es, sich proaktiv mit all diesen Themen zu beschäftigen Man sollte sich also einfach mal die Zeit nehmen, das eine oder andere zu googeln und sich auch über Arbeitsschutz in der IT zu informieren Bei Auftreten dieser Symptome weiß man dann, was sich dahinter verbergen kann und welche Schritte einzuleiten sind Auf dem Blog von Never Code Alone haben wir ja bereits einige Informationen dazu zusammengestellt

Entwickler: Du bist auch Mitveranstalter des Events Never Code Alone Kannst du uns da vielleicht ein wenig drüber berichten? Welche Ziele hat das Event und was erwartet die Besucher?

Roland Golla: Wir verfolgen das Ziel, einen wesentlichen Beitrag zur Steigerung der Softwarequalität in Deutschland zu leisten Hierzu versorgen wir Entwickler auf unseren Events mit neuem Wissen Dabei ist es sicherlich eine Besonderheit von Never Code Alone, dass es bei uns keinen Frontalunterricht gibt Stattdessen führen die Speaker jeweils eine halbe Stunde in ein Thema ein, und danach arbeiten Speaker und Teilnehmer per Funktastatur gemeinsam an der Lösung eines konkreten Problems Wir machen das Ganze jetzt schon seit ein paar Jahren und wissen aus Erfahrung, dass Live Coding jede Menge Spaß bringt, die Soft Skills verfeinert und man im Team echt starke Software schreiben kann Und was uns besonders freut: Insgesamt werden unsere Events sehr gut von den Teilnehmern angenommenDie Teilnehmer können den Ticketpreis in Höhe von 10 Euro zu 100% spenden, oder das auch auf dem Event tun

Roland Golla ist PHP-Trainer und Consultant Er setzt sich ein für Arbeitsschutz in der IT, gute Arbeitgeber und bessere Arbeitsbedingungen Mit NCA möchte er die Softwarequalität in Deutschland steigern

Der Beitrag Arbeitsschutz in der IT: Konkrete Probleme und praktische Lösungen ist auf entwicklerde erschienen


.NET Core 3.0 Preview 8: Updates für ASP.NET Core und Blazor (14.08.2019 12:31:05)

Die achte Preview für NET Core 30 ist mit einigen Feinschliffen erschienen, um die Stabilität und Zuverlässigkeit weiter zu erhöhen Preview 8 kann wie bereits Preview 7 in der Produktion eingesetzt werden Einige Neuerungen gibt es für ASPNET Core und Blazor

Microsoft hat die neueste Vorschauversion seines Open-Source-Frameworks veröffentlicht: NET Core 30 Preview 8 Der Fokus liegt erneut auf Zuverlässigkeit und Stabilität, weshalb keine neuen Features eingefügt wurden In den enthaltenen Updates für ASPNET Core und Blazor hat sich jedoch wieder einiges getan, zum Beispiel was die Project Templates betrifft

Wie schon die vorherige Preview besitzt auch Preview 8 eine Go-Live-Lizenz Wird Preview 7 verwendet, muss für die Go-Live-Unterstützung auf die neue Version aktualisiert werden Microsoft empfiehlt weiterhin, dass Anwendungen zunächst in der Preview getestet werden sollten, bevor diese in der Produktion eingesetzt wird

ASPNET Core und Blazor

In der neuesten Preview gibt es Änderungen an den Project Templates für ASPNET Core und Blazor So wurde das Angular Template für ASPNET Core 30 auf Angular 8 aktualisiert, die aktuelle Major-Version der Frontend-Plattform In Visual Studio wurde etwas aufgeräumt: Die Top-Level-Project-Templates für ASPNET Core ? Razor Class Library, Blazor App, Worker Service und gRPC Service ? erscheinen nun ausschließlich im Dialogfenster für ein neues Projekt Bisher tauchten sie dupliziert im Dialogfenster für eine neue ASPNET-Core-Webanwendung auf

Das Blazor Class Library Template wurde durch das Razor Class Library Template ersetzt, das standardmäßig auf die Entwicklung von Razor Components ausgelegt ist Die Blazor Templates erhalten eine neue Namensgebung: aus ?Blazor server-side? wird ?Blazor Service App?, und ?Blazor? wird zu ?Blazor WebAssembly App? In der Kommandozeile werden die Templates via blazorserver bzw blazorwasm erstellt Um eine ASPNET-Core-gehostete Blazor WebAssembly App zu erstellen, kann --hosted eingegeben oder die Option wie gezeigt in Visual Studio ausgewählt werden:

Blazor WebAssembly App in Visual Studio erstellen; Quelle: Microsoft

Zu den weiteren Neuerungen in Preview 8 zählen die hinzugefügte Case Sensitivity für Komponenten in razor-Dateien sowie eine geänderte Wiederverbindungslogik für Blazor Server Apps, falls die Verbindung mit dem Server unterbrochen wurde

Ein NET-Blogeintrag informiert zu NET Core 30 Preview 8, während auf dem ASPNET-Blog die Neuerungen in ASPNET Core und Blazor vorgestellt werden

Der Beitrag NET Core 30 Preview 8: Updates für ASPNET Core und Blazor ist auf entwicklerde erschienen


Divjoy: Neuer Codebase-Generator für React vorgestellt (14.08.2019 12:28:04)

Mit dem neuen Codebase-Generator Divjoy soll es leichter werden, React-Projekte mit verschiedenen zusätzlichen Tools und Frameworks aufzusetzen Das Konzept unterscheidet sich grundlegend von create-react-app und kommt gut an: Innerhalb weniger Stunden nach der Veröffentlichung wurden mit Divjoy schon über 1000 Projekte erzeugt

React mi Bluma für das UI, Firebase für die Authentifizierung und Mailchimp als Newsletter-Tool aufsetzen: Das kann der neue Codebase-Generator Divjoy Zur Verfügung stehen verschiedene Tools und Templates, die über die Divjoy-Website per Klick zusammen gestellt werden können Am Ende wird der notwendige Code zur Verwendung der gewünschten Kombination ausgegeben, kann über einen Web-Editor angepasst und schlussendlich exportiert werden Neben dem Download der Codebase kann auch ein Export auf CodeSandbox erfolgen

Divjoy oder create-react-app: Verschiedene Konzepte

Entwickelt wurde das Projekt von Gabe Ragland, der plant, eine ganze Bibliothek von vorgefertigten Tool-Integrationen und Templates anzubieten Ragland beschreibt es als aufwändigen Prozess, ein React-Projekt mit mehreren weiteren Tools manuell aufzusetzen, da für jeden Teil des Projekts erneut Dokumentationen gelesen und Anpassungen vorgenommen werden müssten Derzeit bringt Divjoy Support für UI-Kits, Frameworks, Authentifizierung, Newsletter, Kontaktformulare und Analytics mit Im UI-Berich kann bislang jedoch nur Bluma als CSS-Framework gewählt werden Bereits in Planung sind Integrationen für Bootstrap und Material UI Auch für andere Kategorien stehen noch nicht alle geplanten Tool-Integrationen bereit

Die Idee, React-Projekte mit wenig Aufwand und einem vorinstallierten Featureset aufsetzen zu können, ist nicht neu Mit create-react-app steht ein von Facebook selbst entwickeltes Package zur Verfügung, das ein vorkonfiguriertes Setup für eine lauffähige React-Anwendung ausliefert create-react-app wird als npm- oder yarn-Package verwendet Das Vorgehen der zwei Projekte zum React-Setup ist jedoch grundlegend verschieden: Das Facebook-Projekt baut zwar auf zahlreichen Tools wie webpack und Babel auf, erzeugt am Ende aber ein Package, das mit nur einer Dependency auskommt, da alle verwendeten Tools abstrahiert werden Hier wird außerdem nicht mit konkreten UI-Bibliotheken gearbeitet, sondern vornehmlich auf Sprachfeatures gesetzt, sodass beispielsweise kein CSS-Präfix verwendet werden muss Eine konkrete UI-Library kommt aber nicht zum Einsatz

Divjoy kann über die Website des Projekts genutzt werden Weitere Informationen zum Projekt sind im Mission Statement nachlesbar, auf Twitter ist das Projekt unter @heydivjoy zu finden

Der Beitrag Divjoy: Neuer Codebase-Generator für React vorgestellt ist auf entwicklerde erschienen


Entwickler Magazin Spezial Vol. 21: Serverless (14.08.2019 11:08:58)

BASIS UND KULTUR ?Serverless bleibt ein kontroverser Begriff? Interview mit Erwin van Eyk DEVELOPMENT Functions und mehr ? für alle Serverless Microservices

BASIS UND KULTUR

?Serverless bleibt ein kontroverser Begriff?
Interview mit Erwin van Eyk

DEVELOPMENT

Functions und mehr ? für alle
Serverless Microservices am Beispiel von Azure

Laufzeitumgebung in AWS Lambda
In nur wenigen Schritten von der Anwendung zur Ausführung gelangen

Die passgenaue Serverless-Security
Grundlegende Aspekte zum Thema Sicherheit bei Serverless-Architekturen

SERVERLESS COMPUTING

Serverlos, nicht kopflos!
Wie man Stolperfallen beim Serverless Computing vermeidet

Serverless-Code in der Cloud
Eine Lösung für bedarfsgerechte Cloud-Computing- Kapazitäten

Serverless Computing mit PHP
Tradition trifft Moderne: PHP im Kontext von Serverless

Kleiner Scope, große Wirkung!
Der Weg vom Set-up zur funktionierenden Serverless-Anwendung

CLOUD UND CONTAINER

Serverless-Container in Azure
Docker-Container ohne eigene Server in der Microsoft- Azure-Cloud

Java Microservices: ab in die Cloud
Hochdynamische Anwendungen mit Containern und Service Meshes

Angular-App via AWS Cloud
Entwicklung und stetige Auslieferung einer Angular-App in der AWS Cloud

Serverlose Webapplikationen mit AWS
Hohe Skalierbarkeit, weitreichende Ressourcen

SERVERLESS-RECHT

Über den Wolken ?
Datenschutzrechtliche Voraussetzungen beim Cloud-Computing

Erwin van Eyk, Ralf Geschke, Andreas Grimm, Arne Limburg, Martin Maier, Sascha Möllering, Frank Pientka, Michael Rohrlich, Lars Röwekamp, Jonas Schweizer, Daniel Stender, Rainer Stropek, Christian Weyer, Boris Wilhelms

Serverless Computing, Azure Functions, Cloud, AWS Lambda, Serverless

Der Beitrag Entwickler Magazin Spezial Vol 21: Serverless ist auf entwicklerde erschienen


Den Monolith fachgerecht zerlegen (14.08.2019 08:23:47)

Micro Frontends oder auch Micro Apps werden in letzter Zeit häufiger diskutiert Nachdem Microservices-Architekturen im Backend wachsenden Anklang finden, schwappt dieser Architekturansatz auch immer öfter ins Frontend Das erste Mal wurden Micro Frontends im ThoughtWorks Technology Radar Ende 2016 erwähnt Seit dieser Zeit haben sich zahlreiche Bibliotheken und Hilfsmittel rund um diesen Architekturansatz entwickelt

Vor dem Einsatz dieser Architekturform sollten Sie sich fragen, ob Micro Frontends die richtige Lösung für Ihre Applikation sind Analog zum Blogartikel von Dan Abramov zum Einsatz der State-Management-Bibliothek Redux ?You might not need Redux? steht auch vor der Implementierung einer Applikation mit Micro Frontends diese Aussage im Raum ?You might not need Micro Frontends? Diese Architekturform hat ihre Vor- und Nachteile, die Sie gegeneinander abwiegen sollten Die Micro-Frontend-Architektur stellt eine grundlegende Architekturentscheidung dar Diese im Nachhinein umzustellen, gestaltet sich aufwendig

Der Gegenentwurf zu einer Micro-Frontend-Architektur ist der klassische Monolith Eine monolithische Applikation besteht aus einer zusammenhängenden Codestruktur Das muss jedoch nicht zwingend bedeuten, dass es sich um unstrukturierten Spaghetticode handelt Ein moderner Monolith weist eine modulare Struktur auf, sodass auch hier zahlreiche Vorteile einer Services-Architektur, wenn auch in abgeschwächtem Ausmaß, greifen Das Ziel von Modularisierung und auch von Micro Frontends ist, in sich geschlossene Teile einer Applikation zu isolieren Im Backend geht die Microservices-Architektur einen Schritt weiter und entkoppelt die einzelnen Module vollständig voneinander, sodass einzelne Prozesse entstehen, die getrennt voneinander entwickelt, veröffentlicht und gewartet werden können Mit Micro Frontends halten viele dieser Vorteile auch Einzug ins Frontend

Die Vorteile von Micro Frontends

Einer der Vorteile von Microservices im Backend ist, dass Sie diese Services unabhängig voneinander skalieren können, indem Sie zusätzliche Instanzen der Services hochfahren Dieses Feature ist bei Microservices im Frontend nicht relevant, da es sich bei den Services nicht um Prozesse, sondern mehr um eigenständige Bausteine des Frontends handelt

Micro Frontends spielen ihre wahre Stärke in der Entkopplung dieser Bausteine über die Grenzen einer bloßen Modularisierung aus Die einzelnen Micro Frontends können ihre eigenen Technologiestacks und internen Architekturen aufweisen Eine Applikation mit einer Micro-Frontend-Architektur kann sich also beispielsweise aus einem Angular-Frontend, einem React-Frontend und einem Vue-Frontend zusammensetzen Jedes dieser Frontends kann von einem eigenständigen Team umgesetzt werden Damit lassen sich komplette Featureteams realisieren, die sich vom Backend bis zum Frontend durchziehen Jedes Team ist damit in der Lage, Features in ihrer Gesamtheit umzusetzen und zu releasen, ohne dass die übrige Applikation in Mitleidenschaft gezogen wird

Die Schattenseiten von Micro Frontends

Im Gegensatz zu einem modularisierten Frontend-Monolithen, dessen Kern in der Regel eine Bibliothek bildet, kann sich eine Applikation mit Micro Frontends aus verschiedenen Bibliotheken zusammensetzen Dem Vorteil der technischen Freiheit steht hier der entscheidende Nachteil eines deutlich erhöhten Transfervolumens entgegen Diesem Nachteil kann zum Teil durch die Optimierung der Pakete, Komprimierung der Übertragung und Lazy Loading entgegengewirkt werden

Entwickler ? das verlorene Handbuch

by Stefan Priebsch thePHPcc

My browser does what?

by Joel Lord Red Hat OpenShift

Nicht nur das erhöhte Volumen, sondern auch potenziell stark unterschiedliche Strukturen in den einzelnen Teilen der Applikation stellen ein Problem dar So wird der Wechsel zwischen den Micro Frontends durch unterschiedliche Architekturansätze oder die Verwendung verschiedener Frameworks erschwert Dies macht sich gerade dann bemerkbar, wenn die verschiedenen Teile des Frontends von einem Team gewartet werden müssen Die Entwickler müssen dann den Überblick über die verschiedenen Technologien und ihre Eigenheiten haben Diesem Problem können Sie in Ihrer Applikation durch Konventionen und eine strikte Qualitätskontrolle begegnen Durch Vorgaben hinsichtlich Technologien und Bibliotheken schränken Sie zwar die Freiheit der Entwickler etwas ein, die Wartbarkeit der Applikation wird dadurch jedoch potenziell erhöht

Zu guter Letzt bringt die Micro-Frontend-Architektur selbst noch den Nachteil einer erhöhten Gesamtkomplexität der Applikation mit sich Der Grund hierfür liegt darin, dass eine Basis für die Micro Frontends geschaffen werden muss Serverseitig werden Microservices meist in Containern deployt und von einer Softwarekomponente orchestriert Clientseitig stellt der Browser die Laufzeitumgebung der Micro Frontends dar Diese müssen in eine zentrale HTML-Seite eingebunden werden, damit ein Benutzer mit der Applikation interagieren kann Für die Integration der verschiedenen Frontend Services existieren verschiedene Ansätze, von denen ich Ihnen einige im Laufe dieses Artikels vorstellen möchte Allen Lösungen ist gemein, dass sie eine mehr oder weniger umfangreiche Abstraktionsschicht erforderlich machen

Vorbedingungen

Angesichts der Nachteile einer Micro-Frontend-Architektur sollten Sie eine solche Architekturentscheidung nicht leichtfertig treffen Ihre Applikation sollte zumindest einige Anforderungen erfüllen:

  • Umfangreicher Funktionsumfang: Durch die erhöhte Komplexität spielt eine Micro-Frontend-Architektur ihre Vorteile erst ab einem bestimmten Funktionsumfang aus Je größer die Applikation und je mehr gut voneinander abgrenzbare Features sie aufweist, desto besser
  • Getrennte Entwicklungsteams: Mit Micro Frontends lassen sich Microservices von der Datenbank über das Backend bis ins Frontend umsetzen Den Teams wird dadurch ein hohes Maß an Autonomie zugesprochen und auch Releases können unabhängig voneinander erfolgen
  • Unterschiedliche Technologien oder Bibliotheken: Häufig lassen sich Probleme durch spezialisierte Lösungen besser lösen Eine Micro-Frontend-Architektur gewährt hier deutlich mehr Freiheiten als ein monolithischer Ansatz

Mögliche Lösungsansätze

Die zahlreichen Lösungsansätze unterscheiden sich durch die verwendeten Technologien, den Aufwand bei der Umsetzung und die Integrierbarkeit der verschiedenen Lösungen Grundsätzlich können mehrere Frameworks und Bibliotheken auf einer HTML-Seite eingebunden werden Der Nachteil ist, dass die Build-Prozesse der einzelnen Lösungen nicht hierauf ausgerichtet sind und es gerade bei komplexeren Applikationen zu Problemen kommen kann Auch die Integration der einzelnen Applikationen kann aufwendig sein

Mehrere Applikationen über iFrames einbinden

Geht es nur darum, mehrere Frameworks auf einer Seite zu betreiben, ist der einfachste Ansatz die Verwendung von iFrames Ein iFrame erlaubt die Einbindung einer HTML-Seite in eine andere Dabei kann die eingebundene Applikation nicht direkt auf den Kontext der Basisapplikation zugreifen, sie wird also in einer Art Sandbox ausgeführt Eine einfache Kommunikation zwischen beiden Applikationsteilen ist über Nachrichten möglich Bei dieser Lösung bleiben die einzelnen Micro Frontends der Applikation vollständig unabhängig voneinander Namens- oder Strukturkonflikte sowie eine gegenseitige Beeinflussung durch Stylesheets sind ausgeschlossen Die Integrationsschicht, also die Basisseite, die selbst eine Single Page Application sein kann, muss sich um die Anzeige und Positionierung der iFrames kümmern Je nachdem, wie aufwendig diese Integrationsschicht gehalten ist, entstehen wiederum Abhängigkeiten zu den einzelnen Applikationen, die unabhängige Releases erschweren Ein Beispiel für solche Abhängigkeiten ist die bedingte Anzeige einer Applikation Eine Bedingung kann beispielsweise lauten: Applikation A, die in Vue implementiert ist, wird nur angezeigt, wenn der Pfad im URL /list lautet; Applikation B, eine React-Applikation, wird nur angezeigt, wenn der Pfad /details aktiv ist Über einen kleinen Umweg über das History API des iFrames kann sogar der Router der jeweiligen Applikation angesprochen werden Aber auch dies erhöht die Kopplung zwischen Integrationsschicht und der Applikation, da die Integrationsschicht Details über die Implementierung kennen muss, hier das Vorhandensein eines Routers

In bestimmten Fällen kann die Implementierung einer solchen iFrame-Lösung durchaus Sinn ergeben ? bei einer zeitlich begrenzten Migration einer Applikation auf eine neue technische Basis beispielsweise Für den Dauerbetrieb aber gibt es für diese Problemstellung wesentlich elegantere Lösungsansätze

Eigene Implementierung mit Web Components

Im Zusammenhang mit Micro Frontends fällt häufig der Begriff Web Components Unter diesem Begriff wird eine Sammlung von Browserschnittstellen zusammengefasst, die einen komponentenbasierten Aufbau einer Applikation ermöglichen Im Kern bestehen Web Components aus Custom Elements, dem Shadow DOM und HTML-Templates

Mit einem Custom Element können Sie den Vorrat der HTML-Tags, die dem Browser bekannt sind, erweitern Ein solches Element definieren Sie in JavaScript als eine Klasse, die von der Basisklasse HTMLElement ableitet Das Shadow DOM ermöglicht eine Entkopplung der Komponente von der übrigen Applikation Dies wird erreicht, indem sowohl die DOM-Struktur der Komponente als auch die Styles komplett eigenständig sind Wird die Komponente in die Applikation eingebunden, ist sichergestellt, dass keine unerwünschten Seiteneffekte von anderen Elementen einwirken HTML-Templates erlauben, wie der Name vermuten lässt, Strukturtemplates Mit ihnen entfällt die Notwendigkeit, manuell Strukturvorlagen zu erzeugen und diese zu verwalten Stattdessen steht mit einem HTML-Template eine Struktur zur Verfügung, die mittels JavaScript in der Web Component gerendert werden kann In Listing 1 sehen Sie ein Beispiel für eine solche Web Component

<template id="helloWorldTemplate">
  <h1>Hello World</h1>
</template>;

class HelloWorld extends HTMLElement {
  constructor {
    super;

    const template = documentquerySelector'#helloWorldTemplate';

    thisattachShadow{ mode: 'open' }appendChild
      templatecontentcloneNodetrue
    ;
  }
}

customElementsdefine'hello-world', HelloWorld;

Im ersten Teil der Web Component sehen Sie ein einfaches Template, das ein h1-Tag mit Text enthält Dieses Template wird im einfachsten Fall direkt in die HTML-Struktur der Applikation eingebettet Die Klasse HelloWorld wird von der HTMLElement-Klasse abgeleitet, die vom Browser zur Verfügung gestellt wird Im Konstruktor wird mit der attachShadow-Methode das Shadow DOM für diese Komponente aktiviert und mit dem Inhalt des Templates befüllt Der letzte Bestandteil, das Custom Element, wird mit der customElementsdefine-Methode definiert Mit diesem Quellcode können Sie dann das <hello-world>-Tag in Ihrer Applikation verwenden und so die Web Component einbinden Diese Konzepte und Schnittstellen können auch die Grundlage für die Integrationsschicht Ihrer Micro-Frontend-Architektur bilden Dabei wird jedes Micro Frontend als eigene Web Component eingebunden Angular Elements sind die Lösung von Angular für diesen Ansatz Dabei werden Angular-Komponenten in Web Components gepackt und können dann verwendet werden Für Vue existiert eine Erweiterung der CLI, um Vue-Komponenten ebenfalls in Web Components zu wrappen Lediglich bei React müssen Sie sich selbst um einen solchen Wrapper kümmern Dieser ist allerdings in wenigen Zeilen implementiert

Web Components mit Angular

Eine Web Component lässt sich mit Hilfe der Angular Elements erzeugen Als Beispiel für ein Micro Frontend mit Angular erzeugen wir eine einfache Beispielapplikation, transformieren diese in eine Web Component und binden diese in eine Applikation ein Zunächst initialisieren Sie Ihre Applikation mit der Angluar CLI Anschließend fügen Sie das für die Angular Elements erforderliche Polyfill mit dem Befehl ng add @angular/elements hinzu Für das Beispiel reicht eine einfache Komponente bereits aus, die im Template lediglich ein h1-Element mit dem Text ?Hello Angular? aufweist

Der wichtigste Teil geschieht im zentralen Modul der Applikation Hier erzeugen Sie das Custom Element mit der createCustomElement aus dem Angular-Elements-Paket Dieses Custom Element registrieren Sie wie eine gewöhnliche Web Component, mit der customElementsdefine-Methode Listing 2 enthält den Quellcode des App-Moduls mit der Registrierung der Komponente

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';

import { HelloAngularComponent } from '/hello-angular/hello-angularcomponent';

@NgModule{
  declarations: [HelloAngularComponent],
  imports: [BrowserModule],
  entryComponents: [HelloAngularComponent],
}
export class AppModule {
  constructorprivate injector: Injector {
    const helloAngular = createCustomElementHelloAngularComponent, {
      injector,
    };
    customElementsdefine'hello-angular', helloAngular;
  }

  ngDoBootstrap {}
}

Bauen Sie nun Ihre Applikation mit dem Kommando ng build –prod –output-hashing none, erhalten Sie eine Reihe von Dateien im dist-Verzeichnis Binden Sie nun die Dateien mainjs, polyfillsjs, runtimejs und scriptsjs in Ihre Applikation ein, können Sie das Custom Element nutzen In Listing 3 sehen Sie den erforderlichen Code

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Angular Web Component</title>
    <script src="dist/mainjs"></script>
    <script src="dist/polyfillsjs"></script>
    <script src="dist/runtimejs"></script>
    <script src="dist/scriptsjs"></script>
  </head>
  <body>
    <hello-angular></hello-angular>
  </body>
</html>

Damit Ihre Applikation funktioniert, müssen Sie die Dateien, die Sie mit dem Buildprozess erzeugt haben, in die indexhtml-Datei einbinden Anschließend können Sie das Custom Element verwenden

Web Components mit React

React unterstützt Web Components nicht direkt Es existieren jedoch zahlreiche Communityprojekte, die Sie bei der Erzeugung von Wrappern für Ihre React-Komponenten unterstützten Alternativ können Sie auch selbst einen solchen Wrapper erzeugen

Ein solcher Wrapper besteht im Kern aus einer Web Component, die Sie in Form einer eigenständigen Klasse implementieren, die von der HTMLElement-Klasse ableitet Innerhalb der connectedCallback-Methode, die ausgeführt wird, sobald die Komponente zum ersten Mal mit dem DOM verbunden wird, kümmern Sie sich um die Erzeugung der React-Strukturen Zunächst erzeugen Sie ein Wurzelelement, an das Sie Ihre React-Applikation binden Außerdem aktivieren Sie das Shadow DOM und rendern schließlich die Applikation mit der render-Methode des ReactDOM-Objekts Im letzten Schritt definieren Sie das Custom Element mit der define-Methode des customElements-Objekts Anschließend können Sie Ihre Web Component nutzen In Listing 4 finden Sie den Quellcode des React Web Component Wrappers

class HelloWorld extends HTMLElement {
  connectedCallback {
    const mountPoint = documentcreateElement'span';
    thisattachShadow{ mode: 'open' }appendChildmountPoint;

    ReactDOMrender<HelloWorld />, mountPoint;
  }
}
customElementsdefine'react-hello-world', HelloWorld;

Eine weitere Lösung zur Implementierung einer Applikation mit einer Micro-Frontend-Architektur ist das Framework single-spa

single-spa

Beschäftigen Sie sich mit Micro Frontends, werden Sie früher oder später mit dem Framework single-spa konfrontiert Dieses Framework ist, wie viele andere JavaScript-Lösungen auch, ein Open-Source-Projekt, das auf GitHub verwaltet wird Die Entwicklung begann Ende 2015 und es wird nach wie vor aktiv weiterentwickelt Neben der Projektseite auf GitHub ist der Einstieg in single-spa die Webseite des Projekts Die Entwickler des Frameworks werben damit, dass Sie bei der Verwendung von single-spa die freie Wahl zwischen unterschiedlichen Frameworks für Ihre Applikation haben und so Angular, Vue und React friedlich nebeneinander existieren können Außerdem wird Lazy Loading unterstützt, was die Ladezeit der Applikation erheblich verbessern kann, da die einzelnen Bestandteile erst geladen werden, wenn sie wirklich gebraucht werden

Wie in den anderen Ansätzen besteht auch eine single-spa-Applikation aus mehreren Teilen In diesem Fall gibt es mit der single-spa-config eine Integrationsschicht, in die die einzelnen Micro Frontends eingebunden werden Die Micro Frontends sind reguläre Single-Page-Applikationen, die durch das Framework zu einer Gesamtapplikation integriert werden

Installation und erste Schritte

Das single-spa-Framework ist modular aufgebaut Den Kern bildet das single-spa-Paket Es bildet die Grundlage Ihrer Applikation und stellt die Integrationsschicht dar In diese werden dann die verschiedenen Micro Frontends integriert Bevor Sie jedoch mit der Installation des Pakets beginnen, sollten Sie eine packagejson-Datei für Ihre Applikation erzeugen, in der Sie alle installierten Abhängigkeiten festhalten Die packagejson-Datei erzeugen Sie mit dem Kommando npm init -y Nach der Ausführung dieses Kommandos können Sie das single-spa-Paket mit dem Befehl npm install single-spa installieren Für die Frameworks und Bibliotheken, die die Grundlage der einzelnen Micro Frameworks bilden, existieren weitere Pakete So installieren Sie für ein React Micro Frontend beispielsweise das single-spa-react-Paket Bei der Gestaltung der einzelnen Applikationsteile sind Sie recht frei Sie können die gesamte Applikation in einer Verzeichnisstruktur verwalten, mit Unterverzeichnissen für die einzelnen Micro Frontends, oder Sie implementieren die einzelnen Teile in separaten Projekten und nutzen einen Paketmanager wie npm oder yarn, um die Applikation zusammenzufügen

Zunächst widmen wir uns jedoch dem Aufbau der Integrationsschicht Diese besteht aus einer HTML-Datei, die den Einstiegspunkt in die Applikation markiert Diese Datei weist lediglich eine Reihe von Containerelementen auf, in die die Micro Frontends eingehängt werden Zusätzlich dazu erzeugen Sie eine JavaScript-Datei, die die Konfiguration der Applikation enthält Die Konfiguration funktioniert ähnlich wie beim JavaScript-Build-System Gulp über Funktionsaufrufe Im Fall von single-spa sind dies die Funktionen registerApplication und start Die registerApplication-Funktion aus dem single-spa-Paket dient zur Registrierung einer Applikation Das erste Argument ist der Name der registrierten Applikation, das zweite eine Funktion, die aufgerufen wird, wenn die Applikation das erste Mal geladen wird Diese Funktion, die auch als loadingFunction bezeichnet wird, muss ein Promise-Objekt zurückgeben, das mit dem Quellcode der Applikation aufgelöst wird Das dritte Argument, das Sie an die registerApplication-Funktion übergeben, ist die activityFunction Funktion Diese gibt an, ob die Applikation aktiviert werden soll Diese Funktion erhält als Argument das windowlocation-Objekt Über dieses haben Sie beispielsweise Zugriff auf den aktuellen Pfad

Damit die Applikation korrekt gebaut werden kann, benötigen Sie einen Build-Prozess, für den Sie die Werkzeuge webpack und babel benötigen webpack dient zum Bundling der Applikation und Babel zur Umsetzung bestimmter Features wie beispielsweise dem ECMAScript-Modulsystem Beispiele für die babelrc– und webpackconfigjs-Datei finden Sie in der Dokumentation von single-spa In Listing 5 finden Sie die packagejson für die Integrationsschicht

{
  "name": "microfrontends",
  "version": "100",
  "description": "",
  "main": "indexjs",
  "directories": {
    "test": "test"
  },
  "scripts": {
    "start": "webpack-dev-server --open",
    "build": "webpack --config webpackconfigjs -p"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "single-spa": "^411"
  },
  "devDependencies": {
    "@babel/core": "^734",
    "@babel/plugin-proposal-object-rest-spread": "^734",
    "@babel/plugin-syntax-dynamic-import": "^720",
    "@babel/preset-env": "^734",
    "@babel/preset-react": "^700",
    "babel-loader": "^805",
    "clean-webpack-plugin": "^201",
    "css-loader": "^211",
    "html-loader": "^055",
    "style-loader": "^0231",
    "webpack": "^4296",
    "webpack-cli": "^330",
    "webpack-dev-server": "^321"
  }
}

In der packagejson-Datei finden Sie neben den allgemeinen Informationen zur Applikation und den installierten Abhängigkeiten noch zwei Einträge unter dem Punkt scripts Mit dem Kommando npm start starten Sie den Webpack Dev Server für den Entwicklungsprozess Der Befehl npm run build dient zum Bauen der Applikation

React-Applikation in single-spa

Jedes Micro Frontend in single-spa benötigt einen leichtgewichtigen Wrapper um die eigentliche Applikation, sodass sie sich über die Integrationsschicht in die Applikation einbinden lässt Für die React-Applikation erzeugen Sie zunächst ein neues Verzeichnis mit dem Namen react-app In diesem Verzeichnis erzeugen Sie ebenfalls eine packagejson-Datei, da jedes Micro Frontend als eigenständige Applikation betrachtet werden kann Anschließend installieren Sie mit dem Kommando npm install react react-dom single-spa-react React selbst sowie die Hilfsbibliothek für die Integration der Applikation in single-spa Für die Integration erzeugen Sie eine Datei mit dem Namen reactappjs Diese Datei übernimmt das Bootstrapping, Mounting und Unmounting der Applikation Listing 6 zeigt den Quellcode dieser Datei

import React from 'react';
import ReactDOM from 'react-dom';
import singleSpaReact from 'single-spa-react';
import App from '/Appjs';

function domElementGetter {
  return documentgetElementById'react-app';
}

const reactLifecycles = singleSpaReact{
  React,
  ReactDOM,
  rootComponent: App,
  domElementGetter,
};

export const bootstrap = [reactLifecyclesbootstrap];

export const mount = [reactLifecyclesmount];

export const unmount = [reactLifecyclesunmount];

Der singleSpaReact-Funktion, die Sie aus dem single-spa-react-Paket importieren, übergeben Sie ein Objekt mit Referenzen auf React und ReactDOM Außerdem definieren Sie die Wurzelkomponente der Applikation über die Eigenschaft rootComponent Mit der Eigenschaft domElementGetter übergeben Sie eine Funktion, die eine Referenz auf das Containerelement, in das die Applikation eingebunden werden soll, zurückliefert Die Datei exportiert die drei Variablen bootstrap, mount und unmount Die Werte dieser Variablen sind jeweils Arrays, die als Inhalte die entsprechende Lifecycle-Methode enthalten, die Ihnen das reactLifecycles-Objekt zur Verfügung stellt Dieses Objekt ist der Rückgabewert der singleSpaReact-Funktion Die Komponente, die Sie der rootComponent übergeben, ist eine gewöhnliche React-Komponente Das bedeutet, dass Sie hier auf alle Features von React zurückgreifen können Es ist an dieser Stelle beispielsweise auch möglich, den React Router einzubinden und so innerhalb der Applikation über URLs zu navigieren

Ein letzter Punkt, der nun noch offen ist, ist die Einbindung der Applikation in die loadingFunction in der Integrationsschicht Hier nutzen Sie die import-Funktion und übergeben ihr den Pfad zur reactappjs-Datei

Angular-Applikation in single-spa

Ähnlich wie mit React funktioniert auch die Integration einer Angular-Applikation In diesem Fall haben Sie die Möglichkeit, entweder mit dem Angular CLI oder, analog zum Beispiel mit React, ohne das CLI zu arbeiten Falls Sie sich für die Variante mit dem CLI entscheiden, müssen Sie zunächst das Angular CLI mit dem Kommando npm install -g @angular/cli installieren Anschließend erzeugen Sie eine neue Applikation mit dem Kommando ng new angular-app Auch hier müssen Sie eine Hilfsbibliothek installieren; dies erreichen Sie mit dem Kommando npm install single-spa-angular-cli Im Gegensatz zu den übrigen single-spa-Paketen, mit denen Sie bisher gearbeitet haben, wird dieses Paket nicht direkt vom single-spa-Team entwickelt, stattdessen handelt es sich hierbei um ein Communityprojekt

Die Konfiguration der Hilfsbibliothek erfolgt wie für das React Micro Frontend Sie importieren den Loader aus dem single-spa-angular-cli-Projekt und konfigurieren ihn, um die Lifecycles für das Bootstrapping, Mounting und Unmounting zu erhalten Bei der Konfiguration übergeben Sie den Namen der Applikation, den Selektor für das Wurzeltag, sowie optional den Selektor für den HTML-Container Die letzte Option ist die baseHref für Ihre Angular-Applikation Listing 7 enthält den erforderlichen Quellcode

import { loader } from 'single-spa-angular-cli';

const lifecycles = loader{
  name: 'hello-angular',
  selector: 'hello-angular',
  baseHref: '/angular',
};

export const bootstrap = [lifecyclesbootstrap];

export const mount = [lifecyclesmount];

export const unmount = [lifecyclesunmount];

export const unload = [lifecyclesunload];

Neben React und Angular werden noch zahlreiche weitere populäre JavaScript Frameworks unterstützt, unter anderem AngularJS, Ember, Preact oder Vue Die Vorgehensweise ist bei allen Frameworks dieselbe: Sie installieren die Hilfsbibliothek, die die Integration in single-spa ermöglicht, konfigurieren sie und starten dann mit der Entwicklung Ihrer Applikation

Fazit

Micro Frontends bringen die Idee von Microservices ins Frontend Einige Vorteile von Microservices spielen im Frontend keine Rolle So ist es beispielsweise irrelevant, einzelne Services zu skalieren Andere Vorteile spielen Micro Frontends ebenfalls aus So können mehrere Teams an einer Applikation arbeiten, ohne dass Probleme entstehen Die einzelnen Micro Frontends können unabhängig voneinander entwickelt werden, jedes Team hat die Möglichkeit, seine eigenen Technologien auswählen und einsetzen Ist die Integrationsschicht der Applikation richtig gewählt, können die einzelnen Teile der Applikation auch unabhängig voneinander veröffentlicht werden

Mit dieser Integrationsschicht steht und fällt die Flexibilität der Micro-Frontend-Architektur Hier stehen Ihnen verschiedenen Varianten zur Umsetzung zur Verfügung, diese reichen von der Verwendung von iFrames über den Einsatz von Web Components bis hin zur Implementierung einer Applikation auf Basis von Bibliotheken wie single-spa

Gerade Frameworks wie single-spa stellen eine vielversprechende Lösung für eine Micro-Frontend-Architektur dar Durch seinen modularen Charakter ist single-spa nicht auf ein einzelnes JavaScript Framework oder einen manuellen Web Component Wrapper angewiesen Die Integrationsschicht ist vergleichsweise leichtgewichtig gehalten und kann um zusätzliche Framework-spezifische Pakete erweitert werden Jedes Micro Frontend, das Sie in Ihre single-spa-Applikation integrieren möchten, benötigt eine Konfiguration, die als Adapter bei der Registrierung in die Integrationsschicht fungiert Zur Erzeugung einer solchen Konfiguration können Sie auf eine Reihe von vorgefertigten Lösungen wie beispielsweise das single-spa-vue-Paket zurückgreifen, das die Integration einer Vue-Applikation erlaubt Bis auf diese Konfiguration handelt es sich bei den Micro-Frontend-Applikationen um reguläre Applikationen, die mit einer angepassten Konfiguration auch ohne single-spa lauffähig sind

Trotz aller Vorteile und der Tatsache, dass die Micro-Frontend-Architektur gerade in aller Munde ist, sollten Sie sich sehr genau überlegen, ob Sie Ihre Applikation auf diese Architektur aufbauen möchten Durch die separate Integrationsschicht und die Verwendung verschiedener Technologien erhöht sich die Komplexität der Applikation erheblich Die Durchsetzung einheitlicher Styles sowie die Vorgabe von Design- und Architekturmustern ist nur schwer möglich Oft lässt sich eine Anwendung auch als gut modularisierter Monolith mit einer geringeren Komplexität umsetzen

PHP Magazin

Dieser Artikel ist im PHP Magazin erschienen Das PHP Magazin deckt ein breites Spektrum an Themen ab, die für die erfolgreiche Webentwicklung unerlässlich sind

Natürlich können Sie das PHP Magazin über den entwicklerkiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen In unserem Shop ist das Entwickler Magazin ferner im Abonnement oder als Einzelheft erhältlich

Der Beitrag Den Monolith fachgerecht zerlegen ist auf entwicklerde erschienen


PyTorch 1.2 ist da: TensorBoard-Support nicht mehr experimentell (13.08.2019 13:27:00)

Die Machine-Learning-Bibliothek PyTorch ist in Version 12 erschienen Mit dem neuen Release geht die bislang experimentelle TensorBoard-Unterstützung in den stabilen Modus über Ebenfalls dabei: Neues für TorchScript und ONNX sowie Breaking Changes

PyTorch 12 wurde veröffentlicht Das Open-Source-Tool für Machine Learning wurde von Facebooks Abteilung für künstliche Intelligenz geschaffen und wird mithilfe der Community weiterentwickelt Nach dem Motto ?Python-First? soll PyTorch eine tiefe Anbindung an die Libraries und Packages der Programmiersprache besitzen Unter anderem daran wurde auch im neuen Release gearbeitet

TorchScript, TensorBoard und ONNX

Zu den Highlights in PyTorch 12 sollen einige JIT-Neuerungen zählen, die TorchScript betreffen Mit dem neuen TorchScript API soll das Konvertieren von nnModule zu ScriptModule leichter vonstatten gehen TorchScript erhält außerdem einen erweiterten Support für Python-Sprachfunktionen und die Python Standard Library Unterstützt werden zum Beispiel Iterator-basierte Konstrukte wie forin-Schleifen, zip und enumerate sowie die meisten Built-in-Funktionen

Die TensorBoard-Unterstützung wurde erstmals in Version 11 als experimentelle Funktion eingeführt Mit PyTorch 12 befindet sie sich nun im stabilen Modus TensorBoard wird als TensorFlows Visualisierungstoolkit bezeichnet und kann neben einem Modell-Graphen und Metriken zum Beispiel Bilder, Text und Audiodaten anzeigen Um loszulegen, kann from torchutilstensorboard import SummaryWriter eingegeben werden

Zudem wurde im aktuellen Release in Zusammenarbeit mit Microsoft der ONNX-Support erweitert und die Dokumentation angepasst Unter anderem wird nun das Exportieren der ONNX-Opset-Versionen 7v12, 8v13, 9v14 und 10 v15 unterstützt Das ONNX-Format Open Neural Network Exchange ist ein offenes Format für Deep-Learning-Modelle, um sie in verschiedenen Tools zu verwenden Es wurde von Microsoft und Facebook entwickelt und wird inzwischen auch von anderen Unternehmen eingesetzt

Weitere Neuerungen

Das neue Release enthält mehrere Breaking Changes, darunter den dtype-Wechsel von torchuint8 zu torchbool Zudem wurden zehn als deprecated markierte Operatoren für lineare Algebra entfernt und einige Bugs behoben Insgesamt habe es dieses Mal über 1900 Commits gegeben

Alles weitere zu PyTorch 12 kann den Release Notes auf GitHub entnommen werden

Der Beitrag PyTorch 12 ist da: TensorBoard-Support nicht mehr experimentell ist auf entwicklerde erschienen


Auf dem Weg zu Angular 9: Neuerungen an Ivy in v9.0.0-next.2 (13.08.2019 10:31:16)

In Angular 900-next2 wird sichtbar, dass das Angular-Team an Ivy arbeitet Eine Neuerung soll die Performance von Ivy verbessern, eine andere behebt einen Bug Außerdem bringt die neue Next-Version zwei weitere Bugfixes mit

Angular 8 hat mit höflicher Verspätung im Juni das Licht der Welt erblickt Doch nach dem Release ist vor dem Release und bereits im Herbst steht Angular 9 auf dem Plan, genauer: im Oktober oder November sollte es soweit sein Ob dieser Termin eingehalten wird, oder Angular 9 doch ein Nikolausgeschenk wird? Wir werden es sehen Doch bis dahin ist es noch ein weiter Weg und zunächst stehen traditionell die kleineren Releases, also Angular 81, 82 usw ins Haus

Angular 9: Die Next-Versionen

Angular 900-next2

Update vom 13 August 2019

Mit Angular 900-next2 steht nun schon das dritte Next-Release für die kommende Major-Version bereit Dieses Mal sind gleich zwei Neuerungen für Ivy mit dabei, den neuen Renderer, der zu Angular 9 fertig gestellt werden soll Der Bugfix für Ivy betrifft das Verhalten bei inkrementellen Änderungen an Komponenten Wenn diese Teil eines NgModules sind, trat bisher ein Fehler auf, weil die Information über den Compilation Scope aus dem NgModule verloren gingen und nicht neu erzeugt wurden Nun wird diese Information über das Interface ComponentScopeRegistry registriert, sodass sie für inkrementelle Kompilierungen verfügbar ist Für die Performance von Ivy wurde ein Refactoring vorgenommen, durch das der Global State im Kontext interpolierter Werte nicht mehr ausgelesen wird, solange es nicht nötig ist

Die weiteren zwei Bugfixes im Release betreffen Bazel und den Compiler Für Bazel wurde das Treeshaking bei der Erzeugung von FESM- und UMD-Bundles deaktiviert Der Bugfix am Compiler betrifft das Entfernen von Whitespace im Wrapping von i18n-Expansions Weitere Informationen zu Angular 900-next2 können dem Changelog auf GitHub entnommen werden


Angular 900-next1

Update vom 9 August 2019

Drei Bugfixes haben es in Angular 900-next1 geschafft Davon betreffen zwei den Language-Service, einer den Upgrade-Bereich Für den Language-Service wurde getSourceFile so konfiguriert, dass es nur für TypeScript-Dateien aufgerufen wird Dem entsprechenden Pull Request ist zu entnehmen, dass es sich dabei um eine Vorbereitung auf die Integration externer Template-Dateien handelt, die künftig vom Angular Language Service Plug-in verarbeitet werden sollen HTML-Dateien müssen davon jedoch ausgeschlossen werden Die zweite Neuerung am Language Service steht in Zusammenhang damit, dass Angulars eigenes LanguageService Interface durch das von TypeScript ersetzt werden soll Diese Änderung an sich ist noch nicht vollzogen worden; auf dem Weg dahin hat man mit dem Release von Angular 900-next1 aber die Definition und QuickInfo kompatibel damit gemacht Details können auch hier im Pull Request gefunden werden

Im Upgrade-Bereich wurde ein Fehler behoben, der bei der Kompilierung von downgegradeden Komponenten auftrat Da AngularJS synchron kompiliert, sollen Komponenten nach dem Downgrade ebenfalls so behandelt werden Das war nicht mehr der Fall und wurde nun über die statische Methode SyncPromiseall wieder implementiert

Weitere Informationen zu den Neuerungen an Angular 900-next1 können wie immer im Changelog auf GitHub gefunden werden


Angular 900-next0

Update vom 1 August 2019

Beta-Versionen heißen jetzt „next“: Angular hat nach dem Release von v80 das Schema bei der Benennung ihrer Versionen verändert Wo zuvor von Beta-Relaeses gesprochen wurde, steht jetzt „next“ im Versionsnamen So auch beim ersten Release mit der Nummer 9 im Titel: v900-next0 wurde veröffentlicht und zeigt, dass Ivy ein großes Thema für die kommende Major-Version ist Viel mehr verraten die Release Notes auf GitHub aber nicht Das erste 9er-Test-Release bringe Verbesserungen und Fixes mit Bezug zu Ivy mit, so ist dort zu lesen Weitere Informationen folgen wohl erst mit der nachfolgenden Version


Angular 8x: Die Minor-Releases

Angular 820

Update vom 1 August 2019

Angular 820 ist fertig Nach einem Release Candidate steht nun das finale Release der Minor Version von Angular zum Download bereit, das alle Neuerungen der Testphase zusammenbringt und einige kleinere Änderungen selbst hinzufügt So bringt v820 beispielsweise Support für TypeScript 35 mit und umfasst insgesamt 14 Bugfixes, die jedoch weitgehend aus den Betas bekannt sind Genau so verhält es sich mit den insgesamt sechs neuen Features im Release, zu denen unter anderem die automatische Migration von Renderer zu Renderer2 gehört Dieses Feature konnte seit Angular 820-next1 getestet werden

Einen Überblick über Angular 820 gibt das Changelog auf GitHub


Angular 820-rc0

Update vom 30 Juli 2019

Angular 820-rc0 bringt eine Neuerung mit, die sich positiv auf die Performance auswirken soll Dazu wurde am Verhalten des Compilers gearbeitet, der nun nicht mehr vom Prototype zu den eigenen Properties kopiert, wenn ein Objekt geklont wird Bis zur Verwendung von Node 12 sei das kein Problem gewesen, da Node in vorherigen Versionen selbst eine Optimierung dafür mitbrachte Das wurde jedoch zugunsten anderer Optimierungen in Node 12 verworfen, sodass nun eine Lösung in Angular implementiert wurde

Progressive Web Apps without frameworks #nomigrations #webstandards #noslides

by Adam Bien adam-biencom

Angular Schematics ? the unknown hero

by Chris Noring Microsoft

JavaScript Testing in der Praxis Teil 1 + 2

mit Dominik Ehrenberg Crosscan und Sebastian Springer MaibornWolff

Fortgeschrittene schwarze Magie in TypeScript

mit Peter Kröner ‚Webtechnologie-Erklärbär‘

Zu den neuen Features im Release gehört, dass $element nun für Upgrades verfügbar ist und in Template Functions von Komponenten eingefügt wird, die geupgraded wurden Das zweite Feature ist eine Neuerung, die Bazel und Ivy zusammen bringt Dazu wurde das Compile Target für Angular in Bazel so verändert, dass nun Ivy verwendet wird Damit soll ein Problem gelöst werden, das mit transitiven Dependencies auftrat, die bisher nicht erzeugt werden konnten, da sie über einen alten Compiler geladen wurde Weitere Informationen dazu können dem entsprechenden Pull Request auf GitHub entnommen werden Eine weitere Änderung für Bazel wird als Bugfix geführt: Die maximale Heap-Größe für node/ngc in Bazel ist von 2GB auf 4GB erhöht worden Damit habe man diesen Wert an den des TypeScript-Compilers angepasst

Weitere Informationen zu diesen Änderungen sowie den drei weiteren Bugfixes am ersten Release Candidate zu Angular 820 sind im Changelog auf GitHub zu finden


Angular 820-next2

Update vom 18 Juli 2019

Mit Angular 820-next2 hat die kommende Minor-Version von Angular 8 vier weitere Bugfixes erhalten Kontinuierlich gearbeitet wird noch immer an Bazel Mit diesem Release wurde eine erst kürzlich vorgenommene Änderung zurück genommen, die den Umgang mit Custom Bazel Compiler Hosts betrifft Die Neuerung „featbazel: allow passing and rewriting an old bazel host“ sei nicht mehr nötig, da der Angular Indexer stabil sei, wie im entsprechenden Pull Request erklärt wird

Die drei weiteren Bugfixes im Release betreffen den Language-Service, das Compiler-CLI und erneut das WTF-Array Details dazu können dem Changelog auf GitHub entnommen werden


Angular 820-next1 veröffentlicht

Update vom 11 Juli 2019

Das zweite Beta-Release für Angular 82 ist da: 820-next1 Auch dieses Update fällt eher klein aus und bringt nur drei Neuerungen mit Darunter ist ein neues Feature für den Core, das die Migration von Renderer auf Renderer2 automatisiert Zu den Änderungen, die dadurch automatisch vorgenommen werden, gehört die automatische Umbenennung der Methoden aus dem alten Renderer Wo dies nicht möglich ist, weil sich die Methoden nicht direkt entsprechen, werden nun automatisch Helper-Funktionen eingefügt, die sicherstellen, dass dennoch valider Code erzeugt wird Weitere Informationen zu den automatisierten Migrationsschritten für Renderer2 können dem entsprechenden Pull Request entnommen werden

Die anderen beiden Neuerungen am Release sind Bugfixes Eins davon betrifft Bazel Hier wurde eine Änderung am Übersetzungssystem rückgängig gemacht, da das System an sich nicht mehr den vollen Dateipfad des Outputs benötigt Der zweite Bugfix betrifft den Compiler, wo nun alle Informationen aus ASTWithSource separat von AST an sich aufgerufen werden können

Weitere Informationen zum Release können wie immer über das Changelog aufgerufen werden


Angular 810 & 820-next0 veröffentlicht

Update vom 8 Juli 2019

Angular 810 ist in der vergangenen Woche final veröffentlicht worden Das erste Minor-Release für Angular 8 hat noch einmal drei Fehler behoben, zwei davon im Bereich des Service-Worker, einen am Core Das Changelog listet diesbezüglich folgende Änderungen auf:

  • core: handle undefined meta in injectArgs #31333 80ccd6c, closes CLI #14888
  • service-worker: cache opaque responses in data groups with freshness strategy #30977 b0c3453, closes #30968
  • service-worker: cache opaque responses when requests exceeds timeout threshold #30977 a9038ef

Angular 820-next0 folgte umgehend auf dieses Release Hier finden sich die gleichen Bugfixes wie in der Minor-Version, darüber hinaus gab es aber auch Neues für Bazel Zwei neue Features sind dabei So kann mit Bazel nun ein individuell festgelegter CompilerHost genutzt und an ngc Compile weitergegeben werden Nötig sei das beispielsweise für Nutzer, die den Compiler Host von TypeScript überschreiben müssen Das zweite Feature hängt mit dieser Änderung unmittelbar zusammen Um sicherzustellen, dass der Angular Indexer bei Google korrekt mit neu gesetzten Bazel Hosts umgehen kann, wurde eine Option eingefügt, mit der alte Bazel Hosts weitergegeben und überschrieben werden können

Weitere Informationen zu beiden Versionen können dem Changelog auf GitHub entnommen werden

Angular 810-rc0

Update vom 27 Juni 2019

Mit Version 810-rc0 steht der erste Release Candidate für Angular 81 bereit Ein neues Feature ist in der Version enthalten: Für AngularJS und Angular sind nun zwei neue Test Helper in der Upgrade/Static-Library verfügbar Diese helfen bei der Verbindung der Injectors der Versionen, ohne dazu vollständig hybride Apps erstellen zu müssen Weitere Details zum neuen Feature können im entsprechenden Pull Request nachgelesen werden

Für Bazel bringt das Release drei Bugfixes mit Darunter ist eine Aktualisierung von ng new schema, mit der es dem gegenwärtigen Status des Angular Schematics angepasst wurde Außerdem sind nun keine nicht unterstützten CSS-Pre-Processors mehr darin enthalten Das dritte Bugfix für Bazel bezieht sich auf Metadata-Builds, die nun keine Schematics-Ordner mehr umfassen

Außerdem bringt das Release auch Bugfixes für den Compiler und Service-Worker mit Weitere Informationen können wie immer dem Changelog auf GitHub entnommen werden


Angular 810-next3

Update vom 21 Juni 2019

Mit Angular 810-next3 steht ein weiteres Preview-Release für Angular 81 zum Download bereit Die Anzahl der Neuerungen in der Version fällt klein aus, nur drei Bugfixes sind enthalten Einer davon betrifft Bazel, dessen Builder Workspace jetzt mit Node 1016 arbeitet Der zweite Bugfix des Release findet sich in getQuickInfoAtPosition, wo any entfernt wurde Außerdem wurde das @deprecated JSDoc-Tag vorläufig aus TestBedStaticget entfernt, da eine Änderung an der Signatur von TestBedget zu einer deutlich höheren Zahl an Deprecation-Warnungen in einigen TypeScript-Projekten geführt hatte Bis dafür eine andere Lösung implementiert wurde, hat man die durch @deprecated erstellten Annotations darum durch reine Textwarnungen ersetzt, wie dem entsprechenden Pull Request zu entnehmen ist

Weitere Informationen zu Angular 810-next3 können wie immer dem Changelog auf GitHub entnommen werden


Angular 810-next2

Update vom 14 Juni 2019

Angular verfolgt offenbar eine neue Strategie bei der Benennung der Versionen Auf das erste Beta-Release von Angular 81 folgten Version 810-next1, sowie inzwischen 810-next2 Während in Next1 nur ein Bugfix am Core vorgenommen wurde, bringt Next2 nun gleich fünf Änderungen mit Drei der Bugfixes betreffen Bazel Das globale Stylesheet wird bei Verwendung von Bazel nun sowohl im Entwicklungsmodus als auch in der Produktion per <link>-Tag in indexhtml referenziert Außerdem verwendet Bazel nun die Components Schematics nicht mehr im Build und es wird keine Änderung an tsconfigjson mehr durch Bazel vorgenommen

Die anderen beiden Bugfixes in Angular 810-next2 betreffen das HttpUploadProgressEvent-Interface, das nun als öffentliches API freigegeben wurde, sowie den Service-Worker Wenn hier navigatorserviceWorkerregister'/ngsw-workerjs' scheitert, wird keine nicht gefangene Fehlermeldung mehr ausgegeben

Weitere Informationen zu Angular 810-next2 können dem Changelog auf GitHub entnommen werden


Angular 810-beta0: Bugfixes und Features geplant

Update vom 4 Juni 2019

Am 30 Mai, zwei Tage nach Veröffentlichung von Angular 8, wurde der erste Schritt in Richtung Angular 9 vollzogen Gemeint ist, dass die erste Beta-Version von Angular 81 veröffentlicht wurde, die bereits jetzt ein relativ großes Release vermuten lässt: Passend zum Datum wurden 30 Bugs gefixt Damit aber nicht genug, denn auch neue Features wird das erste Minor Release des aktuellen Veröffentlichungszyklus‘ enthalten ? immerhin 6 an der Zahl

Features

Eine der neuen Funktionen spricht vor allem jene Entwickler an, die sich um die Verwaltung kümmern und dafür sorgen müssen, dass alles aktuell ist und bleibt: Es wird wohl zukünftig nicht mehr nötig sein, Flags zu aktualisieren, die mit der Datei bazelrc oder der Toolchain zusammenhängen Auch Plattform-Flags für RBE-Builds und -Tests müssen ab Angular 81 wohl nicht mehr extra aktualisiert werden Eine Ausnahme gilt allerdings, wenn es Braking Changes in Bazel gibt, der diese Flags beeinflusst Stattdessen muss lediglich der Pin des @bazel-toolchains Repositorys in der Datei packages/bazel/packagebzl regelmäßig auf Stand gebracht werden Sicherheit geht übrigens vor: Sollte die Rule rbe_autoconfig im Repository @bazel_toolchains keine passende Toolchain-Konfiguration für die Bazel-Version finden, die gerade vom jeweiligen Projekt genutzt wird, zieht sie automatisch den entsprechenden Container und generiert die Konfigs beim Beginn des Builds bzw Tests

Wer transform-Methoden der SlicePipe nutzt, kann sich über die neuen Overloads freuen, die Angular 81 im Gepäck haben wird Dies soll vor allem zur Verwendung von klareren Typen als immer nur any führen Allerdings geht dies mit einem Breaking Change einher, SlicePipe kann ab dem Update lediglich mit einer Anzahl an Werten, einem String, null oder undefined genutzt werden

Bugfixes

In Sachen Bugfixes gab es nach dem Update offenbar einiges nachzubessern Genau 30 Fixes wurden in der ersten Beta-Version von Angular 81 vorgenommen Im Fokus stand unter anderem Bazel, in dessen Zusammenhang nun korrekte Paramter an den http_server unter Windows weitergegeben werden Aber auch am Kern hat man geschraubt Der CSS-Sanitizer erlaubt ab sofort die Nutzung von Klammern in Dateinamen, das war bislang offenbar nicht möglich Außerdem wurde ein unangenehmer Bug gefixt, der dafür sorgte, dass bei einer Migration nicht alle Dateien mitgenommen wurden Gleich sieben Bugs wurden bei der Migration statischer Querys behoben, unter anderem schlug sie mit voreingestellten Standardwerten von Parametern fehl und gab Fehler nicht korrekt aus

  • bazel: allow ts_library interop with list-typed inputs #30600 3125376
  • bazel: Bump ibazel to 0101 for windows fixes #30196 1353bf0
  • bazel: Directly spawn native Bazel binary #30306 2a0f497
  • bazel: Disable sandbox on Mac OS #30460 b6b1aec
  • bazel: Exclude common/upgrade in metadatatsconfigjson #30133 1f4c380
  • bazel: ng test should run specific ts_web_test_suite #30526 e688e02
  • bazel: pass correct arguments to http_server in Windows #30346 3aff79c, closes #29785
  • bazel: update peerDep ranges #30155 4ae0ee8
  • bazel: Use existing npm/yarn lock files #30438 ff29ccc
  • compiler-cli: log ngcc skipping messages as debug instead of info #30232 60a8888
  • core: consistently use ng:/// for sourcemap URLs #29826 392473e
  • core: CSS sanitizer now allows parens in file names #30322 728db88
  • core: fix interpolate identifier in AOT #30243 30d1f29
  • core: migrations not always migrating all files #30269 349935a
  • core: remove deprecated TestBeddeprecatedOverrideProvider API #30576 a96976e
  • core: require ’static‘ flag on queries in typings #30639 84dd267
  • core: static-query migration errors not printed properly #30458 6ceb903
  • core: static-query migration fails with default parameter values #30269 6357d4a
  • core: static-query migration should gracefully exit if AOT compiler throws #30269 509352f
  • core: static-query migration should handle queries on accessors #30327 0ffdb48
  • core: static-query migration should not fallback to test strategy #30458 0cdf598
  • core: static-query migration should not prompt if no queries are used #30254 4c12d74
  • core: static-query usage migration strategy should detect ambiguous query usage #30215 8d3365e
  • core: temporarily remove @deprecated jsdoc tag for a TextBedget overload #30514 f6bf892, closes #29290 #29905
  • language-service: Remove tsserverlibrary from rollup globals #30123 124e497
  • router: ensure historystate is set in eager update mode #30154 b40f6f3
  • router: ensure navigations start with the current URL value incase redirect is skipped #30344 0fd9d08, closes #30340 #30160
  • router: fix a problem with router not responding to back button #30160 3327bd8
  • router: IE 11 bug can break URL unification when comparing objects #30393 197584d
  • router: type cast correctly for IE 11 bug breaking URL Unification when comparing objects #30464 53f3564

Alle weiteren Informationen zur aktuellen Beta-Version von Angular 81 können dem Changelog auf GitHub entnommen werden Dort gibt es auch Details zu den neuen Features und sämtlichen Bugfixes

Der Beitrag Auf dem Weg zu Angular 9: Neuerungen an Ivy in v900-next2 ist auf entwicklerde erschienen


Security-Forscher aufgepasst: Microsoft startet das Azure Security Lab (13.08.2019 09:19:02)

Microsoft nimmt Bewerbungen von Security-Forschern entgegen, um das neue Azure Security Lab auf Herz und Nieren zu prüfen Dort können Attacken auf IaaS-Szenarien untersucht werden Dafür winken Prämien in Höhe von bis zu 300000 Dollar

Microsoft hat das Azure Security Lab ins Leben gerufen, um Schwachstellen in Azure aufzuspüren und aggressiver als bisher zu testen Das soll laut Microsoft Security Response Center MSRC durch ?eine ausgewählte Gruppe talentierter Individuen? geschehen, die im abgeschirmten Testfeld nach Art krimineller Hacker vorgehen

Azure Security Lab

Das Azure Security Lab ist ein Set dedizierter Cloud-Hosts Dort können sich Security-Forscher austoben, um Angriffe im Bereich Infrastructure as a Service zu starten und eventuelle Sicherheitslücken aufzuspüren Im Unterschied zu bisher können sie zudem versuchen, gefundene Schwachstellen aktiv auszunutzen, denn das Security Lab ist von bestehenden Azure-Kunden isoliert Für den Zugang zu einer Windows- oder Linux-VM muss eine Anfrage an Microsoft gestellt werden Neben regelmäßiger Anerkennung sollen die akzeptierten Forscher auch direkten Kontakt zu Security-Experten von Microsoft Azure erhalten

Die höchstdotierte Prämie des Azure Security Lab wurde mit 300000 US-Dollar ausgelobt Sie bezieht sich auf bestimmte Szenarien-basierte Challenges Außerhalb des neuen Testfelds wurde die mögliche Prämie für Sicherheitslücken in Azure unterdessen auf 40000 Dollar verdoppelt

In einem Blogeintrag stellte das MSRC das neue Azure Security Lab vor Weitere Details zu den Prämien gibt es beim Microsoft Azure Bounty Program

Safe Harbor

Gleichzeitig wurde auch die Formalisierung des Safe-Harbor-Prinzips bekanntgegeben Es soll unter anderem dafür sorgen, dass Security-Forscher sich nicht im Rahmen eines der Bug-Bounty-Programme von Microsoft in rechtliche Schwierigkeiten begeben Bei Unklarheiten bezüglich dessen, was durch das Safe-Harbor-Prinzip abgedeckt ist, stellt Microsoft jedoch klar: ?Wenn Zweifel bestehen, fragt uns zuerst!?

Die Safe-Harbor-Bedingungen sind beim MSRC nachzulesen

Der Beitrag Security-Forscher aufgepasst: Microsoft startet das Azure Security Lab ist auf entwicklerde erschienen


State-Management mit Angular und NgRx (13.08.2019 08:31:28)

Die Frontend-Plattform Angular bietet uns viele Möglichkeiten, gut strukturierte, wart- und testbare Architekturen zu entwickeln Die vielen Bausteine einer Applikation machen das Trennen der Verantwortlichkeiten sehr einfach und nachvollziehbar Daher ist Angular auch für große Businessapplikationen ein passender Kandidat

Gerade in großen Businessapplikationen ist das Behandeln des Status State der Anwendung eine der größten Herausforderungen, der wir uns beim Schreiben der Applikation stellen können Um den Überblick zu behalten, ist es wichtig, den aktuellen State der Applikation greifbar zu machen, abzubilden und Änderungen daran nachvollziehbar vorzunehmen

Um diese komplexe Aufgabe zu meistern, haben sich mit der Entwicklung von Angular Projekte entwickelt, die sich dieses Problems annehmen und uns Entwicklern eine Möglichkeit geben, den State einer Applikation zu lesen, ihn zu manipulieren und abzubilden
In diesem Artikel wollen wir zu Beginn den Begriff State erklären, einen Blick auf das Projekt NgRx werfen und erläutern, welches Problem NgRx lösen kann Anschließend werden wir die technische Seite betrachten sowie die Bestandteile von NgRx in einer Angular-Applikation mit Hilfe von Actions, Reducern und Selectors erklären Abschließend demonstrieren wir das Konsumieren eines Stores in einer Component

Wir schauen uns eine simple To-do-Applikation an, die ihre Items mit Hilfe von NgRx aus einem Store holt, diesen mit dem Backend synchronisiert und an der Benutzeroberfläche anzeigt

Der vollständige Code zum Beispiel in diesem Artikel steht Ihnen auf GitHub zur Verfügung

Die Beispielapplikation

Die Applikation ist eine einfache To-do-Applikation, die To-do-Items lesen und schreiben kann Sie kann Items als erledigt markieren und via Routing auf die Detailseite eines einzelnen Items verweisen Sie ist eine einfach gehaltene Aufgabenverwaltungsapplikation mit einem Featuremodul todo, das die Container- und Presentational-Komponenten enthält Die Presentational Components empfangen Daten und kümmern sich darum, wie Daten angezeigt werden; die Container-Components kommunizieren mit dem Backend über Services, die über das Core-Modul eingebunden werden

Was ist State?

Der State einer Applikation kann sich vom kleinsten Detail bis hin zu einem großen, sichtbaren Status einer Applikation erstrecken Es kann ? je nach Anwendung ? alles als State betrachtet und darin gespeichert werden Ist das Menü auf- oder zugeklappt? Welches Theme ist angewählt? Wie viele Datensätze stelle ich gerade dar? Auf welcher Seite bin ich gerade? Bin ich eingeloggt? Kurz gesagt kann grundsätzlich jede Eigenschaft einer Applikation ein Teil des States sein

Das Redux-Pattern

In Applikationen können sich die Eigenschaften des States ändern Sprich: Jedes Mal, wenn der Benutzer mit meiner Applikation arbeitet, wenn sie neue Werte über ein WebSocket empfängt oder wenn aufgrund einer Reaktion auf ein Event Eigenschaften an meiner Applikation geändert werden, verändert sich auch der State der Applikation

Das Redux-Pattern sieht vor, dass man jederzeit einen prognostizierbaren State erstellt, hält und abfragen kann Hierbei sollte der State immer der einzige Punkt sein, auf den meine Applikation sich bezieht Das bedeutet, der State ist die eine Single Source of Truth, also die einzige Quelle der Wahrheit Es gibt genau einen State in der Applikation und er allein gilt als Basis und bestimmt, was die Anwendung darstellt und wie sie sich verhält

Weiter sollte der State nur lesend verfügbar sein Veränderungen direkt am State dürfen nicht möglich sein, sondern sollten immer per spezieller Aktion getriggert werden, die einen neuen aktualisierten State als Ergebnis liefert Um einen neuen State zu erhalten, benötigt man also den alten State und die entsprechende Aktion Action Das Ergebnis ist ein neues State Object, das dann wieder entsprechendes Verhalten oder Aussehen der Applikation nach sich ziehen kann
Änderungen am State finden also mit Actions statt Grundsätzlich gilt: Alter State + Action = neuer State

Hierbei werden Veränderungen am State mit Funktionen bearbeitet, die bei gleicher Eingabe immer dasselbe Ergebnis haben: Pure Functions Diese Funktionen nennt man Reducer Sie manipulieren nicht ein existierendes State Object, sondern geben immer ein neues State Object zurück inklusive der Änderungen, die man via Action forciert hat

Ein Reducer ist eine Funktion, die den alten State und eine Action als Parameter nimmt und ein neues State Object zurückgibt Der State ist somit immutable:

 
currentState, action => newState

Was ist NgRx?

Das Projekt NgRx hilft uns bei der Herausforderung, State in einer Angular-Anwendung zu verwalten Es gibt uns die Möglichkeit, den Status abzufragen, ihn zu verändern und zu verwalten NgRx ist ein Projekt, unter dem mehrere Bibliotheken verfügbar sind, die helfen, Status nach dem Redux-Pattern zu bearbeiten NgRx abstrahiert für uns Entwickler Klassen wie Actions, Selector oder Store und hilft uns, das Redux-Pattern in einer Angular-Applikation abzubilden

Der Store in NgRx bildet die Verknüpfung von Reducern, Actions und States Er nimmt Actions entgegen und leitet sie an einen Reducer weiter; man kann sich auf ihm auch für Aktualisierungen an einem State registrieren

Doch genug der Theorie, schauen wir uns das Ganze in Aktion an Wir haben unsere Applikation in Featuremodule unterteilt Im Folgenden schauen wir uns an, wie wir im Featuremodul Todo mit NgRx und einem Store arbeiten, den State manipulieren und Veränderungen im UI abbilden können

Installieren der Paktete und Anlegen der Dateien und Ordner

Wir können in unserer Applikation mit npm install @ngrx/store @ngrx/effects die erforderlichen Abhängigkeiten installieren Das Angular CLI hat auch einen Befehl zum Scaffolding von Dateien und Ordnern eingebaut: ng add @ngrx/store Hierbei wird etwas Code schon von vornherein generiert Falls der nicht passt, kann man ihn mit verschiedenen Parametern anpassen In unserem Beispiel werden wir die Dateien und Ordner selbst anlegen

Sind die Pakete installiert, können wir im Featureordner todo einen Folder store anlegen Abb 1

Abb 1: Dieser Folder verwaltet unseren kompletten Store und den Status des Featuremoduls ?Todo?

Erstellen des States

Als Nächstes müssen wir den State des Featuremoduls erstellen Der State ist nur ein JavaScript-Objekt, das alles speichern soll, was wir im State ablegen wollen In dem Fall sind das nur unsere To-do-Items und ? falls es dies gibt ? das gerade ausgewählte To-do-Item In der Datei todoreducerts findet unser State seinen Platz:

export interface ReducerTodoState {
  items: Todo[];
  selectedItem: Todo;
}

Interfaces sind in TypeScript passend für Typsicherheit, somit können wir einen initialState erstellen, der uns das geschriebene Interface erfüllt und die Properties mit den Standardwerten initialisiert Listing 1

export interface ReducerTodoState {
  items: Todo[];
  selectedItem: Todo;
}

export const initialState: ReducerTodoState = {
  items: [],
  selectedItem: null,
};

Der State des Todo-Featuremoduls ist beliebig erweiterbar; alles, was das Todo-Modul angeht, findet hier seinen Platz

Definieren der Actions

Wir wissen, dass wir den State nur mit Actions verändern können Somit müssen wir im nächsten Schritt die Actions definieren, die wir an den Store applizieren wollen, um ein neues State-Objekt erhalten zu können Hierbei sind Actions simple TypeScript-Klassen mit einem eindeutigen Identifier Als Property können wir hier im Konstruktor einen payload angeben Dabei handelt es sich um Metadaten, die wir der Action mit auf dem Weg geben können, damit sie den State passend verändern kann Eine Action, die ein bestimmtes To-do-Item abrufen soll, bekommt beispielsweise die ID dieses Items mit, damit wir dies später aus der Action extrahieren und zur HTTP-Abfrage verwenden können

In einer erstellten Datei todo/store/todoactionsts definieren wir eindeutige Identifier für alle kommenden Actions in einem enum Listing 2

export enum ActionTypes {
  LoadAllTodos = '[Todo] Load Todos',
  LoadAllTodosFinished = '[Todo] Load Todos Finished',

  LoadSingleTodo = '[Todo] Load Single Todo',
  LoadSingleTodoFinished = '[Todo] Load Single Todo Finished',

  AddTodo = '[Todo] Add Todo',
  AddTodoFinished = '[Todo] Add Todo Finished',

  SetAsDone = '[Todo] SetAsDone',
  SetAsDoneFinished = '[Todo] SetAsDone Finished',
}

Hierbei ist es sehr übersichtlich, wenn man das Feature in eckige Klammern vor den Identifier schreibt; auch für das Debuggen ist das von Vorteil

Jetzt können wir Klassen erstellen, die als Identifier type den passenden enum-Wert erhalten Falls Sie es benötigen, können Sie zudem einen Payload, mit dem wir die Action mit Daten versehen können, von der aus dem Paket kommenden @ngrx/store-Klasse Action ableiten

Hierbei wird die Kurzschreibweise zum Erstellen von Properties in einer TypeScript-Klasse genutzt Der Parameter im Konstruktor mit dem Accessor vor dem Parameter erstellt netterweise gleichzeitig ein gleichnamiges Property auf der Klasse Listing 3

import { Action } from '@ngrx/store';
import { Todo } from '//models/todo';

export enum ActionTypes {}
// 

export class LoadAllTodosAction implements Action {
  readonly type = ActionTypesLoadAllTodos;
}

export class LoadAllTodosFinishedAction implements Action {
  readonly type = ActionTypesLoadAllTodosFinished;
  constructorpublic payload: Todo[] {}

export class LoadSingleTodoAction implements Action {
  readonly type = ActionTypesLoadSingleTodo;
  constructorpublic payload: string {}
}

export class LoadSingleTodoFinishedAction implements Action {
  readonly type = ActionTypesLoadSingleTodoFinished;
  constructorpublic payload: Todo {}
}

export class AddTodoAction implements Action {
  readonly type = ActionTypesAddTodo;
  constructorpublic payload: string {}
}

export class AddTodoFinishedAction implements Action {
  readonly type = ActionTypesAddTodoFinished;
  constructorpublic payload: Todo {}
}

export class SetAsDoneAction implements Action {
  readonly type = ActionTypesSetAsDone;
  constructorpublic payload: Todo {}
}

export class SetAsDoneFinishedAction implements Action {
  readonly type = ActionTypesSetAsDoneFinished;
  constructorpublic payload: Todo {}
}

Als Letztes bilden wir einen Aggregatstyp, der alle Klassentypen vereint Dieser wird, genauso wie die enums und die Actionklassen, exportiert Listing 4

import { Action } from '@ngrx/store';
import { Todo } from '//models/todo';

export enum ActionTypes {}
// 

export class LoadAllTodosAction implements Action {
    readonly type = ActionTypesLoadAllTodos;
}
// Alle weiteren Action-Klassen

export type TodoActions =
  | AddTodoAction
  | SetAsDoneAction
  | AddTodoFinishedAction
  | SetAsDoneFinishedAction
  | LoadAllTodosAction
  | LoadAllTodosFinishedAction
  | LoadSingleTodoFinishedAction
  | LoadSingleTodoFinishedAction;

Der Typ TodoActions fasst also alle Klassen zusammen, die als Todoaction infrage kommen könnten

Hinzufügen eines Reducers

Mit einem State und den passenden Actions können wir nun einen Reducer schreiben Ein Reducer ist nichts anderes als eine Funktion, die einen State ReducerTodoState und eine Action Typ TodoActions als Parameter erhält und einen neuen State ReducerTodoState zurückgibt Ein Reducer ist der einzige Punkt unserer Applikation, in dem ein neues State-Objekt erzeugt wird Jede Änderung an einem State geht von einem Reducer aus

In der Datei store/todoreducerts definieren wir den Reducer als normale Funktion Listing 5

import { Todo } from '//models/todo';
import { ActionTypes, TodoActions } from '/todoactions';

export interface ReducerTodoState {
  items: Todo[];
  selectedItem: Todo;
}

export const initialState: ReducerTodoState = {
  items: [],
  selectedItem: null,
};

export function todoReducer
  state = initialState,
  action: TodoActions
: ReducerTodoState {
  // manipulate state
}

Jede Action, die später an den Store gegeben wird, kann nun hier behandelt werden Wir können nun im Reducer mit Hilfe eines switch/case auf die Actions reagieren, die den State manipulieren sollen Listing 6

import { Todo } from '//models/todo';
import { ActionTypes, TodoActions } from '/todoactions';

export interface ReducerTodoState {
  items: Todo[];
  selectedItem: Todo;
}

export const initialState: ReducerTodoState = {
  items: [],
  selectedItem: null,
};

export function todoReducer
  state = initialState,
  action: TodoActions
: ReducerTodoState {
  switch actiontype {
    case ActionTypesAddTodoFinished: {
      return {
        state,
        items: [stateitems, actionpayload],
      };
    }

    case ActionTypesLoadAllTodosFinished: {
      return {
        state,
        items: [actionpayload],
      };
    }

    case ActionTypesLoadSingleTodoFinished: {
      return {
        state,
        selectedItem: actionpayload,
      };
    }

    case ActionTypesSetAsDoneFinished: {
      const index = stateitemsfindIndex
        x => xid === actionpayloadid
      ;

      stateitems[index] = actionpayload;

      return {
        state,
      };
    }

    default:
      return state;
  }
}

Wichtig ist hierbei, dass immer ein neues Objekt zurückgegeben wird:

case MyAction: {
  return {
    // new State Object
  };
}

Wir benutzen dabei den Spread-Operator von ES6 `…` um das alte State-Objekt in das neue Objekt zu mergen:

return {
  state
}

Dabei überschreiben wir das zu bearbeitende Property in einer neuen Zeile mit den Informationen, die an die Actions als Metadaten über das Payload Property mitgegeben werden:

return {
  // return a new object
  state, // merge the old state in it
  items: [actionpayload], // overwrite the property ?items? with a new array spreading the payload in it
};

Diese Funktion des Reducers liefert uns bei gleichem Input immer das gleiche Ergebnis ? eins der wichtigsten Konzepte von Reducern

Im Default-Case geben wir den State ohne Manipulation zurück:

default:
  return state;

Im Reducer reagieren wir auch nicht unbedingt auf alle Arten von Actions Nur, falls wir direkt den State verändern wollen, reagieren wir auf die gewünschte Action Die restlichen Actions triggern eventuell Seiteneffekte, sogenannte Effects Die schauen wir uns jetzt an

Asynchrones Arbeiten mit Effects

Vor dem Hintergrund, dass Reducer immer dasselbe Ergebnis bei denselben Parametern geben, haben wir das Problem der Seiteneffekte; angenommen, wir würden HTTP-Kommunikation in den Reducer setzen, wäre das Ergebnis nicht mehr vorhersagbar Denn wie der Server reagiert Ergebnis 404/500/200/…, wissen wir nicht Somit wäre das Ergebnis nicht mehr absehbar und der Reducer würde eventuell auch bei demselben Input unterschiedliche Ergebnisse bringen Weiter sind Reducer immer synchron, HTTP-Kommunikation ist allerdings asynchron

Wir können somit asynchrone Operationen in von NgRx angebotene Effects auslagern Sie bieten uns eine Stelle für HTTP-Kommunikation oder jede andere Art von asynchronem Verhalten

Wir erstellen eine neue Datei todoeffectsts und eine Klasse TodoEffects Wir dekorieren diese Klasse mit dem Decorator @Injectable, da die Klasse einen Actions-Typ injiziert bekommt und einen Service zur HTTP-Kommunikation benutzt Listing 7

@Injectable
export class TodoEffects {
  constructorprivate actions$: Actions, private todoService: TodoService {
    // Effects
  }
}
```
// Ein Effect wird mit dem @Effect-Decorator versehen und filtert aus den übergebenen actions$ den Typ heraus, auf den der spezielle Effekt reagieren will Diesmal als Observable mittels des typeof-Operators

```typescript
 @Effect
  addTodo$ = thisactions$pipe
    ofTypeActionTypesAddTodo,
    // 
  ;

Der typeof-Operator gibt uns die konkrete Action zurück, die wir weiter verarbeiten können Mittels switchMap lösen wir das erste Observable auf und geben über den TodoService ein neues zurück Listing 8

@Effect
  addTodo$ = thisactions$pipe
    ofTypeActionTypesAddTodo,
    switchMapaction: AddTodoAction =>
      thistodoService
        addItemactionpayload
        // 
    
  ;

Nachdem der HTTP Call getätigt wurde, mappen wir das Observable mit einem map-Operator und geben eine neue Action zurück, die über den NgRx Store automatisch wieder an den Reducer gegeben und ? da wir es ja entsprechend implementiert haben ? dort auch behandelt wird Listing 9

@Effect
  addTodo$ = thisactions$pipe
    ofTypeActionTypesAddTodo,
    switchMapaction: AddTodoAction =>
      thistodoService
        addItemactionpayload
        pipe
          map
            todo: Todo => new AddTodoFinishedActiontodo
          
        
    
  ;

Als Payload geben wir in diesem Fall das Ergebnis des HTTP Calls mit der Action zurück, in diesem Fall das hinzugefügte To-do-Item

Beide Files ? Reducer und Effects ? hören auf alle Actions, die wir am Store applizieren Wir behandeln in unserem Beispiel die initialen Actions wie AddTodo in den Effects; dort setzen wir den HTTP Call ab, geben eine AddTodoFinished-Action zurück, die den State wiederum verändert und im Reducer behandelt wird Die anderen Effects implementieren wir ähnlich Listing 10

// imports

@Injectable
export class TodoEffects {
  constructorprivate actions$: Actions, private todoService: TodoService {}

  @Effect
  loadTodos$ = thisactions$pipe
    ofTypeActionTypesLoadAllTodos,
    switchMap =>
      thistodoService
        getItems
        pipe
          map
            todos: Todo[] => new LoadAllTodosFinishedActiontodos
          
        
    
  ;

  @Effect
  loadSingleTodos$ = thisactions$pipe
    ofTypeActionTypesLoadSingleTodo,
    switchMapaction: LoadSingleTodoAction =>
      thistodoService
        getItemactionpayload
        pipe
          maptodo: Todo => new LoadSingleTodoFinishedActiontodo
        
    
  ;

  @Effect
  addTodo$ = thisactions$pipe
    ofTypeActionTypesAddTodo,
    switchMapaction: AddTodoAction =>
      thistodoService
        addItemactionpayload
        pipemaptodo: Todo => new AddTodoFinishedActiontodo
    
  ;

  @Effect
  markAsDone$ = thisactions$pipe
    ofTypeActionTypesSetAsDone,
    switchMapaction: SetAsDoneAction =>
      thistodoService
        updateItemactionpayload
        pipemaptodo: Todo => new SetAsDoneFinishedActiontodo
    
  ;
}

State Selector anbieten

Der vorletzte Schritt erfordert es, den State der Applikation mundgerecht anzubieten Hierfür erstellen wir eine indexts-Datei, damit wir später sauber aus dem Ordner /store/ äquivalent zu /store/indexts importieren können Diese Datei bietet uns die Möglichkeit, den State so anzubieten, dass Components möglichst wenig Mapping- oder Transformationsarbeit erledigen müssen

Da wir uns in einem Featuremodul befinden, registrieren wir später den Feature-State unter einem bestimmten Property, das wir jetzt schon als String definieren können: export const featureStateName = ‚todoFeature‘;

Wir erstellen ein neues Objekt, auf dem wir den Reducer auf ein Property mappen Falls wir im Todo-Feature mehrere Reducer haben sollten, können wir dieses Objekt erweitern Um typsicher zu bleiben, definieren wir zusätzlich ein Interface für den TodoState mit dem Property todo, das den Typ des Reducers ReducerTodoState erhält Das Objekt hat den Typ ActionReducerMap, der generisch ist In diesem Fall geben wir das Interface TodoState als Typ Somit haben wir ein Objekt für das Featuremodul, das mit zukünftigen Reducern erweiterbar ist Listing 11

import { ActionReducerMap } from '@ngrx/store';
import { ReducerTodoState, todoReducer } from '/todoreducer';

export const featureStateName = 'todoFeature';

export interface TodoState {
  todo: ReducerTodoState;
}

export const todoReducers: ActionReducerMap<TodoState> = {
  todo: todoReducer,
};

Wir registrieren später den TodoState unter dem featureStateName = ‚todoFeature‘ auf dem Modul Um unseren Components nach außen nun saubere Teile des States anbieten zu können, und damit diese nicht groß mappen und sich über Properties hangeln müssen, können wir mit Selectors konkrete Teile des States anbieten Da wir als Grundlage immer das komplette State Object nehmen, müssen wir erstmal den Teil des States extrahieren, den wir behandeln wollen, und dann spezifische Selectors auf Properties von diesem State erstellen Um das Haupt-Property des States zu extrahieren, gibt es eine Funktion createFeatureSelector aus dem @ngrx/store-Paket Er selektiert das Property erster Ebene, das des kompletten Features Listing 12

import { ActionReducerMap, createFeatureSelector } from '@ngrx/store';
import { ReducerTodoState, todoReducer } from '/todoreducer';

export const featureStateName = 'todoFeature';

export interface TodoState {
  todo: ReducerTodoState;
}

export const todoReducers: ActionReducerMap<TodoState> = {
  todo: todoReducer,
};

// extract the main property 'todoFeature' from the state object
export const getTodoFeatureState = createFeatureSelector<TodoState>
  featureStateName
;

Diesen Feature-Selector können wir nun als Argument in eine weitere Funktion geben, die createSelector heißt und ebenfalls aus dem @ngrx/store-Paket kommt Mit diesen Selectors können wir konkrete kleine Teile des States anbieten oder auch filtern oder zusammenfassen Diese Selectors werden später von den Components verwendet

Beispielsweise können wir vom State alle nicht erledigten Items herausfiltern Listing 13

export const getTodoFeatureState = createFeatureSelector<TodoState>
  featureStateName
;

export const getAllUndoneItems = createSelector
  getTodoFeatureState, // select featurestate from main state first
  state: TodoState => statetodoitemsfilterx => !xdone // then return all undone items
;

Wir benutzen die Funktion createSelector, geben den Feature-Selector hinein, bekommen den TodoState als Ergebnis und filtern daraufhin die unerledigten Items heraus

Das Gleiche können wir mit den erledigten Items und dem aktuell ausgewählten Item machen, das auch Teil des States ist Listing 14

import {
  ActionReducerMap,
  createFeatureSelector,
  createSelector,
} from '@ngrx/store';
import { ReducerTodoState, todoReducer } from '/todoreducer';

export const featureStateName = 'todoFeature';

export interface TodoState {
  todo: ReducerTodoState;
}

export const todoReducers: ActionReducerMap<TodoState> = {
  todo: todoReducer,
};

export const getTodoFeatureState = createFeatureSelector<TodoState>
  featureStateName
;

export const getAllUndoneItems = createSelector
  getTodoFeatureState,
  state: TodoState => statetodoitemsfilterx => !xdone
;

export const getAllDoneItems = createSelector
  getTodoFeatureState,
  state: TodoState => statetodoitemsfilterx => xdone
;

export const getSelectedItem = createSelector
  getTodoFeatureState,
  state: TodoState => statetodoselectedItem
;

Mittlerweile sieht unser Store-Ordner wie in Abbildung 2 aus

Abb 2: Aktueller ?Store?-Ordner

State mit dem Modul verbinden und Form des State Objects

Unser Store ist nun fertig Wir müssen diesen nur noch auf unserem Modul registrieren Wir können Stores auf dem Root-Modul AppModule mit StoremoduleforRoot{ … } und auf Featuremodulen mit StoreModuleforFeature’nameOfFeature‘, { … } registrieren Die Effekte müssen wir ebenfalls registrieren Hierfür gibt es die Methoden EffectsModuleforRoot[ … ] oder EffectsModuleforFeature[ … ]

Da wir in diesem Fall in einem Featuremodul arbeiten und der State über die komplette Applikation nur ein JavaScript-Objekt ist, können wir genau dieses JavaScript-Objekt auf dem Appmodul registrieren Die Effekte auf root-level sind in diesem Beispiel ebenfalls nicht genutzt, also stellen wir ein leeres Array zur Verfügung Listing 15

import { NgModule } from '@angular/core';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';

@NgModule{
  declarations: [],
  imports: [
    StoreModuleforRoot{},
    EffectsModuleforRoot[],
  ],
  bootstrap: [],
}
export class AppModule {}

Zu diesem Zeitpunkt ist der State der Applikation, der on the fly von NgRx generiert wird, der folgende:

{
  // empty object
}

Auf das Featuremodul TodoModule registrieren wir den State und die Effects mit forFeature… StoreModuleforFeature’nameOfFeature‘, { … } registriert nun ein neues Property auf dem Root State mit dem Namen des Features In unserem Fall exportieren wir es aus der indexts-Datei und es heißt export const featureStateName = ‚todoFeature‘; Anschließend können wir es gemäß Listing 16 registrieren

import { NgModule } from '@angular/core';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';
import { featureStateName, todoReducers } from '/store';
import { TodoEffects } from '/store/todoeffects';

@NgModule{
  imports: [
    //
    StoreModuleforFeaturefeatureStateName, todoReducers,
    EffectsModuleforFeature[TodoEffects],
  ],
  declarations: [
    // 
  ],
}
export class TodoModule {}

Mit der Zeile StoreModuleforFeaturefeatureStateName, todoReducers erweitern wir also den Root State um ein Property todoFeature

Schauen wir uns den State der kompletten Applikation nun mal genauer an:

 
{
  todoFeature: 
}

Der Wert dieses Properties ist in der Variablen todoReducers deklariert, die wir ebenfalls in der Registrierung angeben Sie beschreibt jedoch ebenfalls nur ein Objekt, das wir in der store/indexts schon programmiert haben:

export const todoReducers: ActionReducerMap<TodoState> = {
  todo: todoReducer,
};

Somit ist das State Object, das NgRx generiert, nun das folgende:

{
  todoFeature: {
    todo: //
  }
}

Schauen wir uns den Wert von todo im State Object genauer an, stellen wir fest, dass er auf den todoReducer verweist Der todoReducer war eine Funktion, die uns einen ReducerTodoState zurückgibt

In der Datei store/todoreducerts ist er definiert mit:

export interface ReducerTodoState {
  items: Todo[];
  selectedItem: Todo;
}

Den Wert unseres todo-Properties auf dem State Object ist Listing 17 zu entnehmen

{
  todoFeature: {
    todo: {
      items: Todo[];
      selectedItem: Todo;
    }
  }
}

Wenn wir nun den createFeatureSelector nochmal anschauen, können wir sehen, dass wir genau dieses JavaScript Object als Grundlage für unsere Properties verwenden:

export const getTodoFeatureState = createFeatureSelector<TodoState>
  featureStateName
;

Dieser FeatureSelector nimmt den kompletten State Listing 18 und selektiert das Property mit dem Namen featureStateName, in unserem Fall todoFeature

{
  todoFeature: {
    todo: {
      items: Todo[];
      selectedItem: Todo;
    }
  }
}

Das Ergebnis dieses FeatureSelectors ist das folgende:

todo: {
  items: Todo[];
  selectedItem: Todo;
}

Wenn wir nun mit createSelector eine Abfrage darauf starten, geben wir das bereits selektierte todoFeature vom Typ TodoState in die zweite Abfrage hinein:

export const getAllUndoneItems = createSelector
  getTodoFeatureState, // extract the 'todoFeature' --> todo: { items: [], selectedItem:  }
  state: TodoState => statetodoitemsfilterx => !xdone
;

In der zweiten Zeile dieses Selectors state: TodoState => statetodoitemsfilterx => !xdone; nehmen wir das Ergebnis des ersten Selectors, dem vorigen FeatureSelector, entgegen, taufen das Ergebnis state und greifen auf das Property todoitem etc zu

So wird der State aufgebaut, an ein Modul appliziert, und wir greifen via Selectors auf die Properties zu

State in einer Component konsumieren

Da wir nun den State und die Selectors demystifiziert haben, können wir den Store in unseren Components injecten und ihn verwenden

Wollen wir nun den Store dazu bringen, alle To-do-Items abzufragen ? dazu hören wir in den Effects auf eine GetAllTodos Action ? können wir sie mit der Funktion dispatch… an den Store applizieren:

thisstoredispatchnew LoadAllTodosAction;

Über die Selectors können wir auf unseren Store zugreifen und aus ihm die Informationen abfragen, die uns in der Component interessieren Hierbei bekommen wir ein Observable zurück Wir registrieren uns also auf alle Änderungen an diesem State Object und bekommen es in eine Variable gepusht:

Eine komplette Component könnte also aussehen wie in Listing 19

import { getAllDoneItems, getAllUndoneItems, TodoState } from '@app/todo/store';
import { LoadAllTodosAction } from '@app/todo/store/todoactions';
import { select, Store } from '@ngrx/store';
import { Observable } from 'rxjs';

@Component
export class ContentComponent implements OnInit {

  items$: Observable<Todo[]>;
  doneItems$: Observable<Todo[]>;

  constructorprivate store: Store<TodoState> {}

  ngOnInit {
    thisitems$ = thisstorepipeselectgetAllUndoneItems;
    thisdoneItems$ = thisstorepipeselectgetAllDoneItems;

    thisstoredispatchnew LoadAllTodosAction;
  }
}

Falls wir in dieser Component das Event fangen, das auslöst, dass ein neues Item hinzugefügt werden soll, können wir die AddTodoAction an den Store applizieren und den entsprechenden Payload mitgeben Listing 20

import { getAllDoneItems, getAllUndoneItems, TodoState } from '@app/todo/store';
import { LoadAllTodosAction, AddTodoAction } from '@app/todo/store/todoactions';
import { select, Store } from '@ngrx/store';
import { Observable } from 'rxjs';

@Component
export class ContentComponent implements OnInit {

  items$: Observable<Todo[]>;
  doneItems$: Observable<Todo[]>;

  constructorprivate store: Store<TodoState> {}

  ngOnInit {
    // 
  }

  addTodoitem: string {
    thisstoredispatchnew AddTodoActionitem;
  }
}

Im Template können wir die Daten via Data Binding an die Presentational Component übergeben und uns auf die Events der Components registrieren Listing 21

<div class="starter-template">
  <h1>Todo</h1>
  <p>
    <app-todo-form todoAdded="addTodo$event"></app-todo-form>
  </p>
  <p>
    <app-todo-list
      [items]="items$ | async"
      [doneItems]="doneItems$ | async"
    ></app-todo-list>
  </p>
</div>

Fazit

Im Verlauf dieses Artikels haben wir gesehen, wie man NgRx benutzen kann, um To-do-Items im UI anzuzeigen und sie an ein Backend zu schicken Wir haben alle inkludierten Dateien und Ordner angeschaut und versucht, Selectors und den State zu entmystifizieren

Dabei ist jedoch auch deutlich geworden, dass eine Menge an Code geschrieben werden muss, um das nötige Level an Abstrahierung zu erreichen: Für jede Aktion müssen neue Actions erstellt werden; auch können neue Reducer, Selectors etc wichtig werden oder müssen angepasst werden Das kann, wenn man es konsequent macht, sehr viel Code für ein kleines Feature bedeuten Die Lernkurve ist recht steil, sodass gerade für Anfänger dieses Thema mehr Verwirrung als Klarheit stiften kann

Mit NgRx können wir jedoch auch sehr elegant die große Hürde des State-Managements überwinden, die uns in der Frontend-Entwicklung immer wieder über den Weg läuft Es wird leicht nachvollziehbar, was wann und wo in der Applikation passiert, das Debugging wird verbessert und Bugs werden schneller gefunden Der Store ermöglicht einfaches Testing und die Nachvollziehbarkeit des Verhaltens der Applikation wird verbessert ? und das vereinfacht die Applikation letztendlich wieder enorm Der Code innerhalb einer Component für das Anfragen von Daten oder Triggern von Aktionen ist lediglich ein Einzeiler und unglaublich übersichtlich

Der Beitrag State-Management mit Angular und NgRx ist auf entwicklerde erschienen


HTTP/3, Slim 4.0 und der Motivations-Lifecycle: Unsere Top-Themen der Woche (12.08.2019 13:50:21)

Wer dazu lernt, bleibt motiviert: Unter diesem Motto stellen wir euch auch diese Woche die spannendsten Themen der Vorwoche noch einmal zusammen Wer mehr über den Lifecycle der Motivation lernen oder wissen möchte, was sich mit HTTP/3 ändert, findet hier die richtigen Links

Die Urlaubszeit ist in vollem Gange, trotzdem haben wir spannende Themen für euch: Immerhin ist nicht jede/r zur gleichen Zeit im Urlaub und auch wer frei hat, hat vielleicht Lust auf die ein oder andere interessante Story Und davon hatten wir letzte Woche so einige zu bieten: HTTP/3 ist noch nicht in der Praxis angekommen, aber bereits heute ein spannendes Thema Immerhin soll der neue Standard einiges verändern Electron und React sind hingegen schon lange eine tolle Kombination Und wer noch nie von WebSockets gehört hat, sollte mal einen Blick drauf werfen! Unsere Top-Themen der Woche bieten also auch im Sommer und zur Urlaubszeit eine breite Perspektive auf die Themen der Entwickler-Welt Viel Spaß beim Lesen!

Einfache Desktopanwendungen mit Electron und React erstellen

Eine Desktopapplikation für ein bestimmtes Betriebssystem zu schreiben, ist heutzutage relativ einfach Für die gängigen Betriebssysteme sind zahlreiche Entwicklungsumgebungen und Bibliotheken verfügbar, mit denen mit wenig Aufwand Anwendungen mit grafischer Oberfläche erstellt werden können Allerdings sind die so erstellten Programme nicht plattformunabhängig Hier setzt Electron als vielversprechende Lösung an Wolfgang Schmidt erklärt, wie man eine Webanwendung auf den Desktop bringt

HTTP/3 und QUIC: Was steckt hinter dem nächsten großen Update für HTTP?

Wer nicht gerade als Admin mit der Optimierung von Webservern beschäftigt ist, dürfte kaum zufällig über HTTP/3 stolpern Und wer doch versucht, sich in das Thema einzulesen, trifft erst einmal auf eine verwirrende Anzahl von Akronymen und Bezeichnungen wie qQUIC, iQUIC, HTTP-over-QUIC oder HTTP/QUIC, die nicht gerade selbsterklärend sind Was sich hinter dieser Armada von Abkürzungen versteckt, was sie verbindet und wie es mit HTTP weitergeht, darum geht es in diesem Artikel

Motivation gleich null ? wie der Mitarbeiter-Lifecycle mit der Leistung zusammenhängt

Wenn die Motivation im Keller ist, liegt das oft ganz einfach am Mitarbeiter-Lifecycle Es stellt sich die Frage: Wo stehe ich und wie komme ich da wieder heraus? Das verrät Yasmine Limberger im neusten Teil ihrer Kolumne: Karrieretipps

Vuejs & Material Design: Eine Designsprache, viele Bibliotheken

Material Design ist beliebt, Vuejs ist ebenfalls Was liegt näher, als beide Trends zu vereinen? Genau das tun zahlreiche Bibliotheken: Vuetify, Material Components Vue und zahlreiche weitere Optionen stehen zur Verfügung Wir stellen einige davon vor

PHP Micro-Framework: Slim 400 erschienen

Die Slim Hauptversion 400 wurde mit zahlreichen Änderungen und Verbesserungen veröffentlicht Unter anderem wurde eine PSR-15-Middelware-Unterstützung implementiert Was ist sonst noch neu?

Weitere spannende Themen der Woche:

  • Serg Hospodarets auf der iJS 2018: Native JavaScript-Module: import {Browsers, Nodejs}; export {production};
  • Hermes: Facebooks neue JavaScript-Engine für Android auch mit API-Level <19 nutzbar
  • WebSockets als interessante Alternative für Backend-for-Frontend 
  • React 169 mit neuer Roadmap veröffentlicht: Noch kein Concurrent Mode
  • Wie Managed Kubernetes das DevOps-Leben besser macht

Der Beitrag HTTP/3, Slim 40 und der Motivations-Lifecycle: Unsere Top-Themen der Woche ist auf entwicklerde erschienen


P++: Ein PHP-Dialekt, der die Community vereint? (12.08.2019 12:10:29)

Die PHP-Welt ist gespalten: Braucht die Programmiersprache eine radikale Erneuerung oder nicht? Um die Lager wieder zu vereinen, hat Zeev Suraski nun das Konzept P++ vorgestellt: Ein Dialekt innerhalb der Sprache soll es möglich machen, PHP in Zukunft sowohl dynamisch als auch statisch typisiert zu nutzen Noch ist aber nichts entschieden

Zeev Suraski, PHP-Core-Entwickler, hat ein Konzept vorgestellt, das die zerstrittenen Lager der PHP-Community vereinen soll: P++ ist der Codename für einen PHP-Dialekt, der im Core verbleiben, bewährtes erhalten und trotzdem radikale Neuerungen ermöglichen soll Suraski sieht darin einen Mittelweg, auf dem die derzeit zerstrittenen Lager der Community wieder zusammenfinden sollen Aber worum geht es dabei genau?

P++: Worum geht es überhaupt?

Soll PHP bei der dynamischen Typisierung bleiben, die es traditionell verwendet, oder strikter typisiert werden? Soll die Sprache weiterhin Short Tags umfassen, die von manchen Entwicklern als eine Art Altlast empfunden werden? Braucht PHP komplexere oder fortgeschrittenere Features oder reicht das, was derzeit vorhanden ist? Muss der Fokus auf der Abwärtskompatibilität erhalten bleiben, den PHP traditionell setzt oder dürfen neue Versionen damit brechen?

Die PHP-Community teilt sich zu diesen Fragen in zwei Lager auf, wie Suraski beschreibt Ein Teil der Community möchte an der klassischen Philosophie von PHP festhalten, wozu die Einfachheit und dynamische Typisierung, sowie der Fokus auf Abwärtskompatibilität gehören Das andere Lager vertritt die entgegengesetzte Position Suraski selbst sagt, dass er sich eher als Traditionalist sieht, den Wunsch nach Veränderung allerdings nachvollziehen kann Darum hat er das Konzept von P++ zur Diskussion gestellt

P++: Was sich ändern könnte

P++ soll kein Fork von PHP sein, sondern einen Dialekt etablieren, der dazu genutzt werden kann, bestimmte Features parallel in mehreren Versionen zu implementieren Die zu nutzende Version könnte dann im Code markiert werden, beispielsweise über einen speziellen P++-Header Grundlegend soll jedoch weiterhin ein gemeinsamer Sprachkern genutzt werden, sodass keine zwei Projekte parallel geführt werden und kein unabhängiger Fork entsteht Suraskis Konzept sieht vor, dass Entwickler auf der Ebene einzelner Dateien entscheiden können, welchen Dialekt sie verwenden möchten Auch sei denkbar, eine Namespace-basierte Definition für Frameworks einzuführen

Als Nachteil am Konzept benennt Suraski die Gefahr einer Fragmentierung der Community Er geht jedoch davon aus, dass das bereits der Fall ist, und dass keine Lösung für PHP gefunden werden könne, die beiden Lagern gerecht werde Ein ewiger Support für PHP 74 und eine  große Veränderung zu PHP 8 würden beispielsweise bedeuten, dass neue Features und Performance-Verbesserungen nicht mehr für alle PHP-Anwender verfügbar gemacht werden könnten

P++ oder Editions?

Neben Suraski hatte auch Nikita Popov einen Vorschlag zum Umgang mit den zwei Lagern in der Community vorgelegt Popov hat dazu das Konzept der Rust Editions heran gezogen, die genutzt werden, um ein bestimmtes Featureset zu deklarieren Details zu den Unterschieden der Konzepte und offenen Fragen auf dem Weg zu einer friedlichen Kooperation beider Lager können dem FAQ zu P++ sowie Suraskis Mailinglist-Nachricht „Bringing Peace to the Galaxy“ entnommen werden Noch steht nicht fest, wie es mit PHP weitergehen wird

Auch der Name für Suraskis Konzept gehört zu den offenen Fragen, die im FAQ genannt werden: P++ ist nur ein Arbeitstitel, und es gehöre, so drückt es Suraski aus, zu den größten Herausforderungen auf einem Weg zur Lösung, einen vernünftigen Namen dafür zu finden

Der Beitrag P++: Ein PHP-Dialekt, der die Community vereint? ist auf entwicklerde erschienen


Diese Seite wurde in 0.229033 Sekunden geladen