<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<title type="text">Cross-Platform-Blog.de</title>
<generator uri="https://github.com/mojombo/jekyll">Jekyll</generator>
<link rel="self" type="application/atom+xml" href="http://www.cross-platform-blog.de/feed.xml" />
<link rel="alternate" type="text/html" href="http://www.cross-platform-blog.de" />
<updated>2017-10-28T22:47:11+02:00</updated>
<id>http://www.cross-platform-blog.de/</id>
<author>
  <name>Gregor Biswanger</name>
  <uri>http://www.cross-platform-blog.de/</uri>
  <email>gregor.biswanger@web-enliven.de</email>
</author>


<entry>
  <title type="html"><![CDATA[Electron.NET – Erstelle eine minimale MusicPlayer App mit ASP.NET Core 2 für den Desktop]]></title>
 <link rel="alternate" type="text/html" href="http://www.cross-platform-blog.de/electron.net/electron.net-musicplayer-app-mit-asp.net-core/" />
  <id>http://www.cross-platform-blog.de/electron.net/electron.net-musicplayer-app-mit-asp.net-core</id>
  <updated>2017-10-27T00:00:00-00:00</updated>
  <published>2017-10-27T00:00:00+02:00</published>
  
  <author>
    <name>Gregor Biswanger</name>
    <uri>http://www.cross-platform-blog.de</uri>
    <email>gregor.biswanger@web-enliven.de</email>
  </author>
  <content type="html">
    &lt;p&gt;Der Blog richtet sich in der Regel an die Entwicklung von Cross-Plattform Lösungen mit JavaScript. Diesmal gibt es eine besondere Ausnahme, denn gemeinsam mit meinem Microsoft MVP Kollegen und Freund  &lt;a href=&quot;https://twitter.com/robert0muehsig&quot; title=&quot;https://twitter.com/robert0muehsig&quot; target=&quot;_blank&quot;&gt;Robert Mühsig&lt;/a&gt;, habe ich ein neues Open-Source Projekt gestartet: &lt;a href=&quot;https://github.com/ElectronNET/Electron.NET&quot; title=&quot;https://github.com/ElectronNET/Electron.NET&quot; target=&quot;_blank&quot;&gt;Electron.NET&lt;/a&gt;&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;Wie der Name es schon erahnen lässt, haben wir ein Electron Derivat für.NET Core entwickelt. Dies ermöglicht die Cross-Plattform Desktop Entwicklung mit C# und ASP.NET Core. Wir haben das Rad nicht neu erfunden, die darunterliegende Runtime basiert auf Electron. So baut Electron.NET auf eine bereits hochentwickelte und stabile Plattform auf.&lt;/p&gt;

&lt;p&gt;Dieser Blog-Post zeigt mit einem einfachen Beispiel, wie simpel es ist, mit Electron.NET und ASP.NET Core 2 eine Cross-Plattform Desktop Software zu entwickeln. Es handelt sich hierbei um einen MusicPlayer. Dieser greift auf das Musik-Verzeichnis zu und kann dann ein beliebiges Lied abspielen.&lt;/p&gt;

&lt;p&gt;Vorbereitungen für den Start:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nodejs.org&quot; title=&quot;www.nodejs.org&quot; target=&quot;_blank&quot;&gt;Node.js (v.8.x)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Das letzte &lt;a href=&quot;https://www.microsoft.com/net/download/core&quot; title=&quot;https://www.microsoft.com/net/download/core&quot; target=&quot;_blank&quot;&gt;.NET Core SDK&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.visualstudio.com/downloads/&quot; title=&quot;https://www.visualstudio.com/downloads/&quot; target=&quot;_blank&quot;&gt;Visual Studio 2017&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;ein-neues-aspnet-core-2-projekt-anlegen&quot;&gt;Ein neues ASP.NET Core 2 Projekt anlegen&lt;/h2&gt;
&lt;p&gt;Aus den Projektvorlagen wählen wir eine „ASP.NET Core Web Application“. Der Name lautet hierbei &lt;strong&gt;MyElectronMusicPlayer&lt;/strong&gt;. Für dieses Beispiel reicht ein komplett leeres Projekt aus. Achte darauf, dass oben .NET Core in Version 2.0 ausgewählt ist.&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/05/01-new-asp.net-core-project.jpg&quot;&gt;&lt;img src=&quot;/images/05/01-new-asp.net-core-project.jpg&quot; alt=&quot;Neues ASP.NET Core Projekt&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/05/02-empty-template.jpg&quot;&gt;&lt;img src=&quot;/images/05/02-empty-template.jpg&quot; alt=&quot;Leeres Template&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Abbildung 1 – Ein neues ASP.NET Core 2 Projekt anlegen&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Jetzt muss die MVC Erweiterung über den NuGet Package Manager installiert werden:&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;Install-Package Microsoft.AspNetCore.Mvc -Version 2.0.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nach der Installation, gibt es ein paar Dinge, die wir zur &lt;strong&gt;Startup.cs&lt;/strong&gt; hinzufügen müssen. Konfigurieren wir zunächst die App, um das MVC-Framework zu verwenden.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureServices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IServiceCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddMvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Im zweiten Schritt, konfigurieren wir die App so, dass sie die MVC-Anforderungsausführungspipeline (Routing) mit einer Standardroute verwendet.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IApplicationBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IHostingEnvironment&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseMvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;routes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MapRoute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{controller=Home}/{action=Index}/{id?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Jetzt, da das MVC-Framework hinzugefügt wurde, können wir einen Controller und eine View erstellen. Hierzu legen wir einen neuen Ordner namens Controller an. Per Rechtsklick auf diesen, fügen wir einen neuen Controller hinzu.&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/05/03-new-controller.jpg&quot;&gt;&lt;img src=&quot;/images/05/03-new-controller.jpg&quot; alt=&quot;Neuer Controller&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/05/04-empty-controller.jpg&quot;&gt;&lt;img src=&quot;/images/05/04-empty-controller.jpg&quot; alt=&quot;Leerer Controller&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/05/05-controller-name.jpg&quot;&gt;&lt;img src=&quot;/images/05/05-controller-name.jpg&quot; alt=&quot;Controllername&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Abbildung 2 – Einen neuen Controller hinzufügen&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Der HomeController wird mit einer Standardmethode namens Index hinzugefügt. Klicken wir mit der rechten Maustaste auf View() und wählen AddView.&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/05/06-new-view.jpg&quot;&gt;&lt;img src=&quot;/images/05/06-new-view.jpg&quot; alt=&quot;Neue View&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/05/07-default-view.jpg&quot;&gt;&lt;img src=&quot;/images/05/07-default-view.jpg&quot; alt=&quot;Viewname&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Abbildung 3 - Eine neue View hinzufügen&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ein neuer Views-Ordner mit Index.cshtml wurde automatisch angelegt. Das ASP.NET MVC Core Projekt ist jetzt für die Implementierung der Logik bereit.&lt;/p&gt;

&lt;h2 id=&quot;electronnet-hinzufügen&quot;&gt;Electron.NET hinzufügen&lt;/h2&gt;
&lt;p&gt;Es sind nur wenige Schritte nötig, um unsere ASP.NET MVC Core 2 Anwendung auf Electron.NET zum Laufen zu bringen. Zuerst muss die &lt;a href=&quot;https://www.nuget.org/packages/ElectronNET.API/&quot; title=&quot;https://www.nuget.org/packages/ElectronNET.API/&quot; target=&quot;_blank&quot;&gt;Electron.NET API&lt;/a&gt; über den NuGet Package Manager installiert werden:&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;PM&amp;gt; Install-Package ElectronNET.API&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In der &lt;strong&gt;Program.cs&lt;/strong&gt;-Datei wird dann die &lt;code class=&quot;highlighter-rouge&quot;&gt;UseElectron&lt;/code&gt; WebHostBuilder-Extension hinzugefügt.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IWebHost&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;BuildWebHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WebHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateDefaultBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseElectron&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UseStartup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Startup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Das war auch schon alles, damit Electron.NET für das Projekt verwendet werden kann. Bis jetzt würde allerdings beim Ausführen vom Projekt nichts passieren. Die Anwendung würde einfach im Hintergrund laufen. Da wir keinen Hintergrundprozess programmieren wollen, wird bei der &lt;strong&gt;Startup.cs&lt;/strong&gt;-Datei ein kleiner Bootstrap-Code für das Anzeigen von einem Hauptfenster implementiert. Zusätzlich möchten wir als Option die Security deaktivieren. So dass wir später ohne Probleme auf das Musik-Verzeichnis zugreifen können.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IApplicationBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IHostingEnvironment&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsDevelopment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseDeveloperExceptionPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseMvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;routes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MapRoute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{controller=Home}/{action=Index}/{id?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;nf&quot;&gt;Bootstrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Bootstrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BrowserWindowOptions&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;WebPreferences&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WebPreferences&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;WebSecurity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Electron&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WindowManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateWindowAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;zugriff-auf-das-dateisystem&quot;&gt;Zugriff auf das Dateisystem&lt;/h2&gt;
&lt;p&gt;Beim &lt;strong&gt;HomeController&lt;/strong&gt; benötigen wir jetzt den Zugriff auf das Dateisystem. Dazu bietet uns die Electron.NET API die Möglichkeit den Pfad der aktuellen Plattform für das Musik-Verzeichnis zu ermitteln. Mit .NET Core greifen wir dann auf die Dateinamen innerhalb des Verzeichnisses zu. Das Ergebnis liefern wir dann direkt an die View weiter.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ElectronNET.API&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ElectronNET.API.Entities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft.AspNetCore.Mvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Collections.Generic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.IO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;MyElectronMusicPlayer.Controllers&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HomeController&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Controller&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IActionResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;musicPath&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Electron&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetPathAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PathName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;music&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mp3Files&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetFiles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;musicPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;*.mp3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SearchOption&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TopDirectoryOnly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mp4Files&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetFiles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;musicPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;*.mp4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SearchOption&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TopDirectoryOnly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;musicFiles&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;musicFiles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mp3Files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;musicFiles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mp4Files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;musicFiles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;die-oberfläche&quot;&gt;Die Oberfläche&lt;/h2&gt;
&lt;p&gt;Die Oberfläche und Funktionalität wird für dieses Beispiel unspektakulär und einfach gehalten. So soll nur eine Liste der Dateien angezeigt werden, die durch einen Button-Klick das gewünschte Lied abspielt. Dazu wird die HTML5 Audio-Klasse eingesetzt.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;@model List&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;viewport&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;width=device-width&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My Electron Music Player&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;charset=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf-8&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;My Music&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
        @foreach (string musicFile in Model)
        {
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                 @System.IO.Path.GetFileNameWithoutExtension(musicFile)

                &lt;span class=&quot;nt&quot;&gt;&amp;lt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;onclick=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;playMusic('@musicFile.Replace(@&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&quot;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&quot;/&quot;)')&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Play&lt;span class=&quot;nt&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        }
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;playMusic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;musicFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;audio&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Audio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`file:///&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;musicFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;audio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;start-der-electronnet-anwendung&quot;&gt;Start der Electron.NET Anwendung&lt;/h2&gt;
&lt;p&gt;Für das Ausführen der Electron.NET Anwendung wird die &lt;a href=&quot;https://www.nuget.org/packages/ElectronNET.CLI&quot; title=&quot;https://www.nuget.org/packages/ElectronNET.CLI&quot; target=&quot;_blank&quot;&gt;Electron.NET CLI&lt;/a&gt; benötigt. Die Installation kann leider &lt;strong&gt;nicht&lt;/strong&gt; über NuGet wie gewohnt erfolgen. Das Paket muss ausschließlich über die &lt;code class=&quot;highlighter-rouge&quot;&gt;.csproj&lt;/code&gt;-Projektdatei referenziert werden. Dazu folgenden Eintrag hinzufügen:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
       &lt;span class=&quot;nt&quot;&gt;&amp;lt;DotNetCliToolReference&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Include=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ElectronNET.CLI&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Version=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;*&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Anschließend in der Console &lt;code class=&quot;highlighter-rouge&quot;&gt;dotnet restore&lt;/code&gt; eingeben.&lt;/p&gt;

&lt;p&gt;Bei einem neuen Electron.NET Projekt, muss zu Beginn einmalig &lt;code class=&quot;highlighter-rouge&quot;&gt;dotnet electronize init&lt;/code&gt; eingegeben werden. Hierzu wird eine &lt;code class=&quot;highlighter-rouge&quot;&gt;electron.manifest.json&lt;/code&gt;-Datei angelegt und ein neues Debug-Profil bereitgestellt.&lt;/p&gt;

&lt;p&gt;Mit dem Befehl &lt;code class=&quot;highlighter-rouge&quot;&gt;dotnet electronize start&lt;/code&gt; wird dann die ASP.NET MVC Core 2 Anwendung als Desktop-Software gestartet.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;&lt;strong&gt;Wichtig!&lt;/strong&gt; Beim ersten Mal dauert der Startvorgang etwas. Wir arbeiten daran, dies in Zukunft zu beschleunigen.&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/05/08-Electron.NET-Music-Player.jpg&quot;&gt;&lt;img src=&quot;/images/05/08-Electron.NET-Music-Player.jpg&quot; alt=&quot;Electron.NET Music Player&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Abbildung 4 – Die Electron MusicPlayer Anwendung&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;das-builden&quot;&gt;Das Builden&lt;/h2&gt;
&lt;p&gt;Die Electron.NET CLI ermöglich ebenfalls das Builden einer ausführbaren Anwendung für Windows, Mac und Linux. Dazu gibt es allgemein den Befehl &lt;code class=&quot;highlighter-rouge&quot;&gt;dotnet electronize build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Für einzelne Plattformen:&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;dotnet electronize build win&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;dotnet electronize build osx&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;dotnet electronize build linux&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;&lt;strong&gt;Wichtig!&lt;/strong&gt; Für das Builden von Mac-Anwendungen wird ein Mac oder Linux benötigt.&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;fazit&quot;&gt;Fazit&lt;/h2&gt;
&lt;p&gt;Wir haben in diesem Beispiel gesehen, wie einfach mit Electron.NET eine Desktop-Software mit ASP.NET MVC Core 2 erzeugt wird. Der C#-Code greift hierbei auf die Verzeichnisse zu und übermittelt diese Informationen an die MVC-Oberfläche. Normal wäre dies über einen Web-Browser nicht möglich.&lt;/p&gt;

&lt;p&gt;Weitere Beispiele der Electron.NET API demonstriert die API Demo-App. Wer mag kann gerne zur Übung probieren, wie ein OpenFile-Dialog über die API angesprochen wird. So dass unsere Beispielanwendung auch andere Verzeichnisse einlesen kann. Als kleinen Bonus könnte man einen Shortcut hinterlegen, der per Zufall eines der Lieder aus der Liste abspielt. Wer das geschafft hat, kann gerne ein Kommentar hinterlassen 😊&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/ElectronNET/electron.net-musicplayer-sample&quot; title=&quot;https://github.com/ElectronNET/electron.net-musicplayer-sample&quot; target=&quot;_blank&quot;&gt;Hier der MusicPlayer auf GitHub&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/ElectronNET/electron.net-api-demos&quot; title=&quot;https://github.com/ElectronNET/electron.net-api-demos&quot; target=&quot;_blank&quot;&gt;Hier die Electron.NET API Demo App auf GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wie gefällt euch Electron.NET? Ich freue mich auf dein Feedback als Kommentar.&lt;/p&gt;

    &lt;p&gt;&lt;a href=&quot;http://www.cross-platform-blog.de/electron.net/electron.net-musicplayer-app-mit-asp.net-core/&quot;&gt;Electron.NET – Erstelle eine minimale MusicPlayer App mit ASP.NET Core 2 für den Desktop&lt;/a&gt; was originally published by Gregor Biswanger at &lt;a href=&quot;http://www.cross-platform-blog.de&quot;&gt;Cross-Platform-Blog.de&lt;/a&gt; on October 27, 2017.&lt;/p&gt;
  </content>
</entry>


<entry>
  <title type="html"><![CDATA[Interview mit webpack Gründer Tobias Koppers]]></title>
 <link rel="alternate" type="text/html" href="http://www.cross-platform-blog.de/tools/interview-mit-webpack-autor-tobias-koppers/" />
  <id>http://www.cross-platform-blog.de/tools/interview-mit-webpack-autor-tobias-koppers</id>
  <updated>2017-03-04T00:00:00-00:00</updated>
  <published>2017-04-03T00:00:00+02:00</published>
  
  <author>
    <name>Gregor Biswanger</name>
    <uri>http://www.cross-platform-blog.de</uri>
    <email>gregor.biswanger@web-enliven.de</email>
  </author>
  <content type="html">
    &lt;p&gt;Tobias Koppers ist freiberuflicher Software-Entwickler und Berater aus Nürnberg. Bekannt wurde er als Autor von webpack, das weltweit von mehreren Millionen Entwicklern eingesetzt wird. Seine Schwerpunkte liegen bei der JavaScript Entwicklung und Open-Source Projekten. Ich konnte ein Exklusivinterview mit Tobias führen, das ich euch nicht vorenthalten möchte. Viel Spaß beim Lesen.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;&lt;strong&gt;Gregor: Hallo Tobias, die ganze JavaScript-Welt spricht über webpack. Sogar Google setzt darauf und hat es direkt bei der Angular CLI integriert. Ich bin auch ganz besonders stolz darauf, dass webpack aus Nürnberg, der Nähe meiner Heimatstadt Ingolstadt stammt. Erzähl uns doch mal die Geschichte, wie du auf die Idee gekommen bist und wie webpack sich so schnell verbreiten konnte.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tobias:&lt;/strong&gt; Hi Gregor. Tatsächlich war Google in der Entstehung auch involviert, wenn auch nur indirekt. Bevor ich süchtig nach JavaScript wurde habe ich auch mal mit Java gearbeitet. Hier gibt es ein Tool von Google welches es ermöglicht eine clientseitige Web-Anwendung in Java zu entwickeln: Google Web Toolkit (GWT). Das ist ein Java-zu-JavaScript Compiler für SPAs, welcher auch Basis von einigen Google Anwendungen ist.&lt;/p&gt;

&lt;p&gt;Beim GWT hat mir besonders ein Feature besonders gefallen: Code Splitting. Dies ermöglicht unter anderem selten benutzten Code erst später nachzuladen. Diese Feature ist besonders wichtig für große Anwendungen um die initiale Ladezeit klein zu halten. Mir hat dieses Feature in existierenden JavaScript-Tooling gefehlt (2012) und daraus ist letztlich webpack entstanden.&lt;/p&gt;

&lt;p&gt;Das heißt webpack ist mit dem Fokus auf Code Splitting entstanden, und meiner Meinung nach war das auch der Grund warum es sich so verbreitet hat. Mit wachsender Größe von Webanwendungen und gleichzeitigen verstärkten Gebrauch von mobilen Geräten (mit schwacher Netzanbindung) sie die Relevanz von Code Splitting mit der Zeit gewachsen. Ansonsten lässt sich die gewünschte Performance nur schwer umsetzen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gregor: Viele vergleichen webpack mit Task-Tools wie NPM-Scripts, Grunt und Gulp. Einige haben mit webpack auch wirklich ihren Ersatz gefunden. Ich selbst nutze zukünftig auch nur noch NPM-Scripts und webpack. Wie stehst du zu diesem Thema und nutzt du ein Task-Tool zusätzlich zu webpack?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tobias:&lt;/strong&gt; Mir selbst reichen NPM Skripte auch aus. Tatsächlich ist aber eigentlich nicht richtig webpack als Ersatz für Grunt/Gulp zu bezeichnen. Grunt und Gulp fallen in eine andere Kategorie von Tools wie webpack. Grunt, Gulp und NPM Skripte sind Task Runner.&lt;/p&gt;

&lt;p&gt;Webpack ist ein Module Bundler. Dies sind Werkzeuge mit unterschiedlichen Zielen. Es ist aber richtig, dass webpack die notwendigen “Tasks” zum Bauen einer Web-Anwendung soweit vereinfacht, dass es eventuell ein Overkill ist Task Runner wie Grunt und Gulp zu verwenden und NPM Skripte ausreichen. NPM ist also der Ersatz für Grunt und Gulp.&lt;/p&gt;

&lt;p&gt;Allerdings haben Task Runner immer noch ihre Daseinsberechtigung für andere Aufgaben neben vom reinen Bauen der Web-Anwendung: Deployment, Linting, Versionsmanagement, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gregor: Bei meinen JavaScript Schulungen bekomme ich bei meinen Teilnehmern immer wieder mit, wie schwer Ihnen der Einstieg mit webpack fällt. Hast du dazu auch schon Feedback bekommen? Wenn ja, hast du auch schon Ideen, wie man das verbessern kann?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tobias:&lt;/strong&gt; Ja tatsächlich kommt dieses Feedback auch an. Allerdings sagen auch viele Nutzer, dass sobald es erstmal “Klick” gemacht hat, ist es eigentlich recht einfach zu benutzen. Wer webpack “kann” sagt sogar, dass es einfacher ist als die vorherigen Tools.&lt;/p&gt;

&lt;p&gt;Ich glaube dieses Feedback ist darin begründet, dass die Konzepte von webpack deutlich von den Konzepten anderer Tools abweichen. Vor allem bei der Migration von Grunt/Gulp zu webpack. Task Runner haben eher eine imperative Konfiguration, d. h. man beschreibt die Schritte die vom Task Runner auszuführen sind. Webpack hingegen hat eine deklarative Konfiguration, d. h. man beschreibt nicht die Schritte die webpack ausführen soll, sondern beschreibt nur die Art und Weise wie diese Schritte auszuführen sind bzw. wie das Ergebnis auszusehen hat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gregor: Was steht noch auf deiner Agenda? Welche Features sind bei der nächsten webpack-Version geplant?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tobias:&lt;/strong&gt; Das ist noch nicht ganz klar. Es gibt so viele Dinge die möglich sind. Um nur einige spannende Punkte zu nennen:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Scope Hoisting: kleine und performantere Art die Module zusammenzuhängen&lt;/li&gt;
  &lt;li&gt;WebAssembly: Unterstützung von binärem Code in der WebApp&lt;/li&gt;
  &lt;li&gt;Persistenter Cache: Schnelleres initiales Kompilieren&lt;/li&gt;
  &lt;li&gt;CSS (und HTML) als First-Class-Citizen: Schönere Unterstützung für Stylesheets (und HTML)&lt;/li&gt;
  &lt;li&gt;Und noch viele spannende Kleinigkeiten&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In welcher Reihenfolge diese angegangen werden entscheiden die Nutzer und Sponsoren. Wir haben eine Voting-Seite auf dieser für die nächsten Punkte abgestimmt werden kann. Jeder bekommt täglich einen Einflusspunkt und Sponsoren und Contributor bekommen für Spenden bzw. Contributions goldene Einflusspunkte. Das geschieht aus der Motivation heraus Sponsoren und Contributor etwas zurückgeben zu wollen. Außerdem ist es natürlich interessant was Nutzer am meisten wollen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gregor: Kannst du uns einen Top Best Practictes Tipp zu webpack verraten?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tobias:&lt;/strong&gt; On-Demand-Loading verwenden. Es ist super einfach zu verwenden und bringt unglaublich viel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gregor: Was sind deine persönlichen Ziele? Werden wir bald alle lesen, dass du bei Google in Mountain View arbeiten wirst? ;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tobias:&lt;/strong&gt; Eher nicht. Ich werde demnächst als Freelancer arbeiten. Ich werde versuchen so viel wie möglich an Open Source zu arbeiten und das Ganze über Spenden zu finanzieren. Da Spenden allerdings meist nicht reichen, werde ich den Rest über Auftragsarbeiten oder Consulting finanzieren. Ich bin schon gespannt wie das läuft. Vielleicht findet sich ja ein Sponsor der mir ein paar zusätzliche Wochen Open Source finanziert (hey Google ;) ).&lt;/p&gt;

&lt;p&gt;Der Aufwand ein Open Source Projekt zu maintainen wird häufig unterschätzt. Aktuell verbrauchen Code Reviews und Issues 80% meiner Zeit. Ich komm kaum noch dazu selbst Code zu schreiben, geschweige denn zu Refactorn. Ich muss sogar teilweise Pull Requests erstmal eine Zeit liegen lassen bevor ich die Zeit finde sie im Detail anzuschauen. Das ist natürlich demotivierend für die Contributor. Ich denke, dass sich das ändern kann, wenn ich Vollzeit an webpack arbeite. Hoffentlich habe ich dann auch mehr Zeit um selbst mehr Code zu schreiben.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gregor: Ganz vielen Dank, dass du dir die Zeit für uns und das Interview genommen hast! Danke auch für webpack, das uns JavaScript-Entwickler extrem unterstützt. Ich liebe dein Tool!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tobias:&lt;/strong&gt; Gerne. Mein Dank geht zurück an die Community. Webpack ist nicht “mein” Tool, es wird von mehr als 500 Contributoren gestaltet. Zu webpacks Erfolg zählt auch sein großes Ecosystem.&lt;/p&gt;


    &lt;p&gt;&lt;a href=&quot;http://www.cross-platform-blog.de/tools/interview-mit-webpack-autor-tobias-koppers/&quot;&gt;Interview mit webpack Gründer Tobias Koppers&lt;/a&gt; was originally published by Gregor Biswanger at &lt;a href=&quot;http://www.cross-platform-blog.de&quot;&gt;Cross-Platform-Blog.de&lt;/a&gt; on April 03, 2017.&lt;/p&gt;
  </content>
</entry>


<entry>
  <title type="html"><![CDATA[JavaScript Coding Dojo: Der DictionaryReplacer Kata]]></title>
 <link rel="alternate" type="text/html" href="http://www.cross-platform-blog.de/coding-dojo-katas/javascript-coding-dojo-dictionaryreplacer-kata/" />
  <id>http://www.cross-platform-blog.de/coding-dojo-katas/javascript-coding-dojo-dictionaryreplacer-kata</id>
  <updated>2017-03-02T00:00:00-00:00</updated>
  <published>2017-02-03T00:00:00+01:00</published>
  
  <author>
    <name>Gregor Biswanger</name>
    <uri>http://www.cross-platform-blog.de</uri>
    <email>gregor.biswanger@web-enliven.de</email>
  </author>
  <content type="html">
    &lt;p&gt;Das Dojo ist die Übungshalle in den japanischen Kampfkünsten und die Übungen werden hierbei Kata genannt. Beim Coding Dojo geht es darum eine Übungsaufgabe (Kata) zu meistern. Ganz nach dem Motto „Learning by doing“. Der Cross-Platform-Blog wird jetzt regelmäßig JavaScript Katas veröffentlichen.&lt;/p&gt;

&lt;h2 id=&quot;der-dictionaryreplacer-kata&quot;&gt;Der DictionaryReplacer Kata&lt;/h2&gt;
&lt;p&gt;Bei diesem Kata handelt es sich um einen einfachen String-Replacer. Die Inspiration zu diesem Kata entstand durch einen Vortrag von Cory Haines zum Thema Übungen. Erstelle eine Methode, die einen String und ein Dictionary erhält. Darin soll nun jeder Key des Dictionaries, welcher mit einem Dollarzeichen beginnt und endet, mit dem entsprechenden Wert des Dictionaries ersetzt werden.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;&lt;strong&gt;Tests:&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;input:&lt;/strong&gt; “”, &lt;strong&gt;dictionary:&lt;/strong&gt; empty, &lt;strong&gt;output:&lt;/strong&gt; “”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;input:&lt;/strong&gt; “$temp$”, &lt;strong&gt;dictionary:&lt;/strong&gt; [“temp”, “temporary”], &lt;strong&gt;output:&lt;/strong&gt; “temporary”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;input:&lt;/strong&gt; “$temp$ here comes the name $name$”, &lt;strong&gt;dictionary:&lt;/strong&gt; [“temp”, “temporary”] [“name”, “John Doe”], &lt;strong&gt;output:&lt;/strong&gt; “temporary here comes the name John Doe”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Schwierigkeit:&lt;/strong&gt; Einfach&lt;br /&gt;
&lt;strong&gt;Dauer:&lt;/strong&gt; Ca. 5-20 Minuten&lt;br /&gt;
&lt;strong&gt;Quelle:&lt;/strong&gt; &lt;a href=&quot;http://codingdojo.org/kata/DictionaryReplacer/&quot; title=&quot;Der DictionaryReplacer Kata&quot; target=&quot;_blank&quot;&gt;http://codingdojo.org/kata/DictionaryReplacer/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;vorbereitungen-für-den-start&quot;&gt;Vorbereitungen für den Start&lt;/h2&gt;
&lt;p&gt;Für das Projekt wird folgendes benötigt:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nodejs.org&quot; title=&quot;www.nodejs.org&quot; target=&quot;_blank&quot;&gt;Node.js&lt;/a&gt; (Läuft auf Windows, Mac und Linux)&lt;/li&gt;
  &lt;li&gt;TypeScript&lt;br /&gt;
In der Konsole &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install typescript –g&lt;/code&gt; eingeben&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://code.visualstudio.com&quot; title=&quot;http://code.visualstudio.com&quot; target=&quot;_blank&quot;&gt;Visual Studio Code&lt;/a&gt; (Läuft auf Windows, Mac und Linux)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Für dich ist bereits ein fertiges Übungsprojekt auf GitHub hinterlegt:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;git clone https://github.com/GregorBiswanger/KataDictionaryReplacer.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Anschließend innerhalb des Projekts mit &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install&lt;/code&gt; alle nötigen Module installieren.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Du kannst kein TypeScript? Keine Sorge! TypeScript == JavaScript und du kannst dein bisheriges JavaScript Wissen ohne Probleme einsetzen. Die Vorteile? Spüre es selbst bei der Codeübung. ;) Ein wesentlicher Unterschied ist, dass die Dateiendung hierbei mit *.TS endet. Die TypeScript erstellten JavaScript und Source Map-Dateien habe ich für die Übung von Visual Studio Code ausblenden lassen. Das sorgt für eine bessere Übersicht. Im Dateisystem existieren diese allerdings.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;der-start&quot;&gt;Der Start&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Öffne das Projekt mit Visual Studio Code&lt;/li&gt;
  &lt;li&gt;Starte den TypeScript Compiler mit der Tastenkombination &lt;code class=&quot;highlighter-rouge&quot;&gt;[strg] + [shift] + [b]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Beim Terminal gibst du innerhalb deines Projekts &lt;code class=&quot;highlighter-rouge&quot;&gt;npm test&lt;/code&gt; ein&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Jetzt läuft der Testrunner Jasmine und bemerkt Dateiänderungen automatisch. Hast du einen zweiten Monitor, ist dort für den Terminal der ideale Platz. So kannst du während der Entwicklung den aktuellen Status beobachten.&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/04/vscode-npm-test.jpg&quot;&gt;&lt;img src=&quot;/images/04/vscode-npm-test.jpg&quot; alt=&quot;npm start&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;der-prozess&quot;&gt;Der Prozess&lt;/h2&gt;
&lt;p&gt;Wichtig bei Coding Dojo ist mit Babysteps die Lösung zu meistern. Löse jede Aufgabe Schritt für Schritt und nicht alles auf einmal. Dieses Prinzip ist für viele Entwickler nicht einfach, aber genau die Vorteile an dieser Herangehensweise lehrt uns ein Coding Dojo.&lt;/p&gt;

&lt;p&gt;Welche Aufgaben Schritt für Schritt erfüllt werden müssen, findest du im &lt;code class=&quot;highlighter-rouge&quot;&gt;spec&lt;/code&gt;-Verzeichnis. Beim &lt;code class=&quot;highlighter-rouge&quot;&gt;src&lt;/code&gt;-Ordner findet dann die eigentliche Programmierung statt.&lt;/p&gt;

&lt;h2 id=&quot;debugging&quot;&gt;Debugging&lt;/h2&gt;
&lt;p&gt;Das Projekt hat bereits alle nötigen Visual Studio Code Einstellungen, so dass du ohne Probleme innerhalb der Tests oder beim eigenen Code debuggen kannst. Dazu einfach mit der &lt;code class=&quot;highlighter-rouge&quot;&gt;[F9]&lt;/code&gt;-Taste einen Breakpoint setzen und mit &lt;code class=&quot;highlighter-rouge&quot;&gt;[F5]&lt;/code&gt; das Debugging starten.&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/04/vscode-jasmine-debugging.jpg&quot;&gt;&lt;img src=&quot;/images/04/vscode-jasmine-debugging.jpg&quot; alt=&quot;Unit Test Debugging&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;regeln&quot;&gt;Regeln&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Löse das Kata bis alle Tests grün sind&lt;/li&gt;
  &lt;li&gt;Anschließend kopiere deine Lösung hier auf jsfiddle.net:
  &lt;strong&gt;&lt;a href=&quot;https://jsfiddle.net/GregorBiswanger/n6zm9wz7/&quot; title=&quot;jsfiddle.net&quot; target=&quot;_blank&quot;&gt;https://jsfiddle.net/GregorBiswanger/n6zm9wz7/&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Klicke links oben auf den „Update“-Button und kommentiere deinen Link hier bei diesem Blog-Post&lt;/li&gt;
  &lt;li&gt;Erst dann, darfst du deine Lösung gerne mit bereits Kommentierten Lösungen vergleichen&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/04/jsfiddle-typescript-jasmine.jpg&quot;&gt;&lt;img src=&quot;/images/04/jsfiddle-typescript-jasmine.jpg&quot; alt=&quot;jsfiddle kata mit typescript und jasmine&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;lets-get-ready-to-rumble&quot;&gt;Let’s get ready to rumble!&lt;/h2&gt;
&lt;p&gt;Bei meinen JavaScript Schulungen mache ich immer wieder gerne Katas mit meinen Teilnehmern. Ich liebe es anschließend die unterschiedlichen Lösungen zu begutachten. Ich bin auch jetzt gespannt, wie du die Aufgabe meistern wirst. Und jetzt: Let’s get ready to rumble!&lt;/p&gt;


    &lt;p&gt;&lt;a href=&quot;http://www.cross-platform-blog.de/coding-dojo-katas/javascript-coding-dojo-dictionaryreplacer-kata/&quot;&gt;JavaScript Coding Dojo: Der DictionaryReplacer Kata&lt;/a&gt; was originally published by Gregor Biswanger at &lt;a href=&quot;http://www.cross-platform-blog.de&quot;&gt;Cross-Platform-Blog.de&lt;/a&gt; on February 03, 2017.&lt;/p&gt;
  </content>
</entry>


<entry>
  <title type="html"><![CDATA[Node.js: Die REST Web-API Express.js mit TypeScript]]></title>
 <link rel="alternate" type="text/html" href="http://www.cross-platform-blog.de/nodejs/typescript/nodejs-die-rest-web-api-expressjs-mit-typescript/" />
  <id>http://www.cross-platform-blog.de/nodejs/typescript/nodejs-die-rest-web-api-expressjs-mit-typescript</id>
  <updated>2017-30-01T00:00:00-00:00</updated>
  <published>2017-01-30T00:00:00+01:00</published>
  
  <author>
    <name>Gregor Biswanger</name>
    <uri>http://www.cross-platform-blog.de</uri>
    <email>gregor.biswanger@web-enliven.de</email>
  </author>
  <content type="html">
    &lt;p&gt;Bei Node.js hat sich ein Web Application Framework stark durchgesetzt: Express.js. Dieses wurde vom Sinatra-Framework aus der Ruby-Welt inspiriert. Es erweitert das vorhandene Build-In Modul &lt;code class=&quot;highlighter-rouge&quot;&gt;http&lt;/code&gt; von Node.js, damit das Entwickeln moderner Webanwendungen einfacher gestaltet wird:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Vergleichbar mit der Microsoft Web-API (Nur besser :))&lt;/li&gt;
  &lt;li&gt;Kommunikation mit REST (HTTP) per Standard&lt;/li&gt;
  &lt;li&gt;Request/Response-Handling&lt;/li&gt;
  &lt;li&gt;Routing&lt;/li&gt;
  &lt;li&gt;View Templating&lt;/li&gt;
  &lt;li&gt;Session Support&lt;/li&gt;
  &lt;li&gt;Static Files Support&lt;/li&gt;
  &lt;li&gt;Middleware
    &lt;ul&gt;
      &lt;li&gt;Zum Beispiel Funktionen, die sich zwischen Request und Response hängen können (Logger etc.)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Und vieles mehr…&lt;br /&gt;
&lt;!-- more --&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;die-installation&quot;&gt;Die Installation&lt;/h2&gt;
&lt;p&gt;Zuerst wird ein neues Node.js-Projekt mit einer TypeScript Compiler-Konfiguration benötigt. Passend dazu die Visual Studio Code Build- und Debugging-Konfiguration. Diese Schritte wurden bereits im folgenden Artikel ausführlich erklärt:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.cross-platform-blog.de/tools/nodejs/typescript/visual-studio-code-nodejs-mit-typescript-und-debugging&quot; title=&quot;Visual Studio Code: Node.js mit TypeScript und Debugging&quot; target=&quot;_blank&quot;&gt;Visual Studio Code: Node.js mit TypeScript und Debugging&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Zusätzlich wird jetzt Express.js und die TypeScript Deklaration für Express.js benötigt. Dazu innerhalb des Projekts im Terminal folgendes eintippen:&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;npm install express –save&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;npm install @types/express –save-dev&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;das-erste-expressjs-hello-world&quot;&gt;Das erste Express.js „Hello World“&lt;/h2&gt;
&lt;p&gt;Wir legen eine neue &lt;strong&gt;index.ts&lt;/strong&gt;-Datei an oder ersetzen die vorhandene Datei mit dem Inhalt des folgenden Codes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'express'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Hello World'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Der Code ist sehr ähnlich aus dem gewohnten „Hello World“-Beispiel für Node.js. Die Unterschiede: Express.js erstellt automatisch im Hintergrund bei der &lt;code class=&quot;highlighter-rouge&quot;&gt;listen&lt;/code&gt;-Funktion einen Web-Server. Die Abfrage für REST wird explizit vergeben, wie hier zum Beispiel mit &lt;code class=&quot;highlighter-rouge&quot;&gt;get&lt;/code&gt;. Das Routing wird daraufhin mit einem String-Wert festgelegt. Bei der Verarbeitung der Anfrage wird wie gewohnt eine anonyme Funktion ausgeführt, allerdings muss hier kein Stream explizit beendet werden. Darum kümmert sich Express.js automatisch.&lt;/p&gt;

&lt;h2 id=&quot;die-get-aktion-mit-parameter&quot;&gt;Die GET-Aktion mit Parameter&lt;/h2&gt;
&lt;p&gt;Eine REST GET-Aktion wird mittels &lt;code class=&quot;highlighter-rouge&quot;&gt;get&lt;/code&gt;-Funktion hinterlegt. Das Routing wird per String festgelegt und Parameter werden zusätzlich mit Doppelpunkt und Variablenamen gekennzeichnet. Wie folgendes Beispiel zeigt:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/api/sayhello/:name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;isNaN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'No string as name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In Visual Studio Code den TypeScript-Compiler starten &lt;code class=&quot;highlighter-rouge&quot;&gt;[strg] + [shift] + [b]&lt;/code&gt;, falls dieser noch nicht läuft. Als nächstes die Anwendung mit &lt;code class=&quot;highlighter-rouge&quot;&gt;[F5]&lt;/code&gt; ausführen. Anschließend im Browser &lt;strong&gt;http://localhost:3000/api/sayhello/John&lt;/strong&gt; eingeben.
Der Web-Service sollte nun folgenden JSON-Wert zurückliefern:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Folgende Rückgabe-Funktionen sind mit der Get-Funktion möglich:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;render&lt;/code&gt; für HTML-Inhalt mit View Engine&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;send&lt;/code&gt; für Text-Inhalt&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;json&lt;/code&gt; für JSON-Inhalt&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;redirect&lt;/code&gt; zur Weiterleitung&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;queries&quot;&gt;Queries&lt;/h2&gt;
&lt;p&gt;Gewöhnliche Query-Parameter können ebenfalls abgefragt werden. Diese befinden sich unter &lt;code class=&quot;highlighter-rouge&quot;&gt;request.query.PARAMETERNAME&lt;/code&gt;. Ein zusätzliches Festlegen im Routing ist nicht notwendig.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/api/sayhello/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;isNaN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'No string as name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Als nächstes die Anwendung mit &lt;code class=&quot;highlighter-rouge&quot;&gt;[F5]&lt;/code&gt; ausführen. Anschließend im Browser &lt;strong&gt;http://localhost:3000/api/sayhello?name=NodeJS&lt;/strong&gt; eingeben.&lt;/p&gt;

&lt;h2 id=&quot;die-post-aktion&quot;&gt;Die Post-Aktion&lt;/h2&gt;
&lt;p&gt;POST-Aktion mittels &lt;code class=&quot;highlighter-rouge&quot;&gt;post&lt;/code&gt;-Funktion hinterlegen. Damit allerdings reguläre Form-Submit POST-Anfragen verarbeitet werden können, sind noch zwei weitere Pakete zur Installation notwendig:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;npm install body-parser multer --save&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Diese sind relevant zum Parsen von &lt;em&gt;multipart/form-data&lt;/em&gt; und &lt;em&gt;application/x-www-form-urlencoded&lt;/em&gt;. Als Single-Middleware wird &lt;code class=&quot;highlighter-rouge&quot;&gt;upload.array()&lt;/code&gt; zusätzlich bei der Post-Funktion eingebunden. Forms gesendete Daten werden über &lt;code class=&quot;highlighter-rouge&quot;&gt;request.body.VARIABLENAME&lt;/code&gt; abgefragt.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'express'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// For POST-Support&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bodyParser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'body-parser'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;multer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'multer'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;upload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;multer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bodyParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;urlencoded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;extended&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}));&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/api/sayHello'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;isNaN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'No string as name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Hello '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'POST request to homepage'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Zum Testen eignet sich das Tool &lt;a href=&quot;https://www.getpostman.com&quot; title=&quot;Postman&quot; target=&quot;_blank&quot;&gt;Postman&lt;/a&gt;. Bei Postman an erster Stelle „POST“ auswählen und in das URL-Feld &lt;strong&gt;http://localhost:3000/api/sayhello/&lt;/strong&gt; eintippen. Folgende Abfrage kommt dann direkt darunter:&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/03/postman-post.jpg&quot;&gt;&lt;img src=&quot;/images/03/postman-post.jpg&quot; alt=&quot;Post-Anfrage mit Postman&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;p&gt;Jetzt auf den Send-Button klicken und direkt darunter erscheinen die Response-Daten. Die Post-Anfrage kann direkt in Visual Studio Code gedebuggt werden.&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/03/vscode-expressjs-debugging.jpg&quot;&gt;&lt;img src=&quot;/images/03/vscode-expressjs-debugging.jpg&quot; alt=&quot;Post-Anfrage mit Visual Studio Code debuggen&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;fazit&quot;&gt;Fazit&lt;/h2&gt;
&lt;p&gt;Mit Express.js kann man schnell und einfach Web-Services bereitstellen und noch viel mehr. In weiteren Artikeln werde ich noch tiefer und weiter auf das tolle Web Application Framework eingehen.
Der Source-Code für die Beispiele liegt auf GitHub:&lt;/p&gt;

&lt;div&gt;&lt;a href=&quot;https://github.com/GregorBiswanger/VSCodeExpressjsTypeScriptSample&quot; target=&quot;_blank&quot; class=&quot;btn btn-success&quot;&gt;Code on GitHub&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Wie gefällt dir Express.js? Ich bin auf deine Meinung im Kommentar gespannt.&lt;/p&gt;

    &lt;p&gt;&lt;a href=&quot;http://www.cross-platform-blog.de/nodejs/typescript/nodejs-die-rest-web-api-expressjs-mit-typescript/&quot;&gt;Node.js: Die REST Web-API Express.js mit TypeScript&lt;/a&gt; was originally published by Gregor Biswanger at &lt;a href=&quot;http://www.cross-platform-blog.de&quot;&gt;Cross-Platform-Blog.de&lt;/a&gt; on January 30, 2017.&lt;/p&gt;
  </content>
</entry>


<entry>
  <title type="html"><![CDATA[Visual Studio Code: Node.js mit TypeScript und Debugging]]></title>
 <link rel="alternate" type="text/html" href="http://www.cross-platform-blog.de/tools/nodejs/typescript/visual-studio-code-nodejs-mit-typescript-und-debugging/" />
  <id>http://www.cross-platform-blog.de/tools/nodejs/typescript/visual-studio-code-nodejs-mit-typescript-und-debugging</id>
  <updated>2017-27-01T00:00:00-00:00</updated>
  <published>2017-01-27T00:00:00+01:00</published>
  
  <author>
    <name>Gregor Biswanger</name>
    <uri>http://www.cross-platform-blog.de</uri>
    <email>gregor.biswanger@web-enliven.de</email>
  </author>
  <content type="html">
    &lt;p&gt;Die kostenfreie Entwicklungsumgebung Visual Studio Code von Microsoft, bietet eine hervorragende Unterstützung von TypeScript und die Entwicklung von Node.js-Projekten. Dieser Blog-Post zeigt, wie einfach ein neues Node.js-Projekt mit TypeScript-Support erzeugt wird. Gegen Ende wird auch ein kleines „Hallo Welt“-Beispiel im Debug-Modus durchlaufen.&lt;br /&gt;
  &lt;!-- more --&gt;&lt;/p&gt;

&lt;p&gt;Für das Beispiel werden folgende Installationen benötigt:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nodejs.org&quot; title=&quot;www.nodejs.org&quot; target=&quot;_blank&quot;&gt;Node.js - http://www.nodejs.org&lt;/a&gt; (Läuft auf Windows, Mac und Linux)&lt;/li&gt;
  &lt;li&gt;TypeScript&lt;br /&gt;
In der Konsole &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install typescript –g&lt;/code&gt; eingeben&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://code.visualstudio.com&quot; title=&quot;http://code.visualstudio.com&quot; target=&quot;_blank&quot;&gt;Visual Studio Code - http://code.visualstudio.com&lt;/a&gt; (Läuft auf Windows, Mac und Linux)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;ein-neues-projekt&quot;&gt;Ein neues Projekt&lt;/h2&gt;
&lt;p&gt;Für ein neues Projekt wird nur ein neues Verzeichnis benötigt. In Visual Studio Code wird dieses im Menü über &lt;code class=&quot;highlighter-rouge&quot;&gt;File | Open Folder…&lt;/code&gt; geöffnet. Als Projektdatei wird die packages.json-Datei benötigt. Dazu wird in der Konsole &lt;code class=&quot;highlighter-rouge&quot;&gt;npm init -y&lt;/code&gt; eingetippt (In VSCode unter Windows &lt;code class=&quot;highlighter-rouge&quot;&gt;[Strg] + [ö]&lt;/code&gt; die integrierte Konsole öffnen).&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/02/vscode-npm-init.jpg&quot;&gt;&lt;img src=&quot;/images/02/vscode-npm-init.jpg&quot; alt=&quot;Visual Studio Code&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;nodejs-deklaration-dateien-installieren&quot;&gt;Node.js Deklaration-Dateien installieren&lt;/h2&gt;
&lt;p&gt;Damit Visual Studio Code die Funktionen von Node.js per IntelliSense auflösen kann, werden die TypeScript Deklaration-Dateien von Node.js benötigt. Diese installiert man ab TypeScript 2 über den Node Package Manager (NPM). Für Node.js wird dazu &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install @types/node –save-dev&lt;/code&gt; eingegeben. Für andere Pakete würde man dann zum Beispiel: &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install @types/jquery –save-dev&lt;/code&gt; aufrufen.&lt;/p&gt;

&lt;h2 id=&quot;typescript-compiler-konfiguration&quot;&gt;TypeScript Compiler-Konfiguration&lt;/h2&gt;
&lt;p&gt;Für einen geeigneten Node.js-Support mit TypeScript, wird eine Compiler-Konfigurationsdatei benötigt. Diese legen wir im Root-Verzeichnis mit dem Namen &lt;code class=&quot;highlighter-rouge&quot;&gt;tsconfig.json&lt;/code&gt; an. Dank dem JSON IntelliSense-Feature von Visual Studio Code, wird automatisch anhand des Dateinamens eine Autovervollständigung bereitgestellt. Dazu einfach die ersten geschweiften Klammern setzen und das IntelliSense mit der Tastenkombination &lt;code class=&quot;highlighter-rouge&quot;&gt;[Strg] + [.]&lt;/code&gt; auslösen. Die Schema Informationen dazu bezieht sich Visual Studio Code direkt übers Internet. Sollte keine Verbindung möglich sein, entfällt leider der IntelliSense-Support. Tippe dazu die folgende Compiler-Konfiguration:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;compilerOptions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;commonjs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sourceMap&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;watch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Module&lt;/strong&gt;: Bei einer klassischen Web-Anwendung bezieht sich der Browser über das Script-Tag die JavaScript Dateien. Bei Node.js wird der JavaScript code unabhängig einer Web-Seite ausgeführt. Daher wurde ein Modul-System mit dem Namen CommonJS ins Leben gerufen. Dieses ermöglicht das Laden von JavaScript-Dateien aus JavaScript-Code heraus. TypeScript benötigt daher die Information, welches Modul-System eingesetzt wird, um den passenden Code automatisch von „import“ und „export“ generieren zu können.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Map&lt;/strong&gt;: Wie der Name bereits sagt, werden hierbei Dateien generiert, die als Karte für den Debugger-Service dienen. Diese helfen dem Debugger dabei, eine Code-Stelle der TypeScript-Datei auf die generierte JavaScript-Datei aufzulösen. Dank diesem Konzept, wird das Debuggen direkt aus der TypeScript-Datei ermöglicht.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch&lt;/strong&gt;: Damit nicht vor jedem Debugging der TypeScript-Compiler gestartet werden muss, hilft die Watch-Option. Diese beobachtet alle TypeScript-Dateien auf Änderungen. Sollte sich eine Datei ändern, so wird automatisch der Compiler aktiv. So reicht es aus, dass nur einmalig der Compiler gestartet werden muss.&lt;/p&gt;

&lt;h2 id=&quot;das-erste-nodejs-hello-world&quot;&gt;Das erste Node.js „Hello World“&lt;/h2&gt;
&lt;p&gt;Jetzt legen wir eine &lt;strong&gt;index.ts&lt;/strong&gt;-Datei an. Dazu wird folgender Code für ein „Hello World“ Beispiel benötigt:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;http&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'http'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Hallo von Node.js!'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Die erste Zeile beginnt mit einem TypeScript-Spezifischen Keyword &lt;code class=&quot;highlighter-rouge&quot;&gt;import&lt;/code&gt;. Damit weiß TypeScript, dass es zu diesem Modul eine Deklaration existieren muss. Sollte keine Deklarations-Datei oder ein TypeScript-Code im Projekt vorhanden sein, wird wie gewöhnlich einfach &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; geschrieben. Dann greifen wir auf ein Node.js Build-In Modul &lt;code class=&quot;highlighter-rouge&quot;&gt;http&lt;/code&gt; von Node.js zu. Die erste Zeile ist somit vergleichbar wie ein &lt;code class=&quot;highlighter-rouge&quot;&gt;using&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;import&lt;/code&gt; oder &lt;code class=&quot;highlighter-rouge&quot;&gt;include&lt;/code&gt; aus anderen Hochsprachen.&lt;/p&gt;

&lt;p&gt;Ab Zeile 3 wird bereits ein Web-Server erzeugt. Beim Aufruf wird die anonyme Funktion ausgelöst und ein Streaming zum Client ist aktiv. Hier erhalten wir alle Client Anfrageinformationen beim &lt;code class=&quot;highlighter-rouge&quot;&gt;request&lt;/code&gt;-Parameter. Über den &lt;code class=&quot;highlighter-rouge&quot;&gt;response&lt;/code&gt;-Parameter können wir Daten an den laufenden Stream hängen. Dazu wurde die einfache &lt;code class=&quot;highlighter-rouge&quot;&gt;write&lt;/code&gt;-Funktion genutzt, um einen einfachen String-Wert zu senden. Um den laufenden Stream zu beenden, wird die &lt;code class=&quot;highlighter-rouge&quot;&gt;end&lt;/code&gt;-Funktion benötigt.
Mit der &lt;code class=&quot;highlighter-rouge&quot;&gt;listen&lt;/code&gt;-Funktion wird der aktuelle Web-Server für den definierten Port aktiv. Das war es auch schon.&lt;/p&gt;

&lt;h2 id=&quot;typescript-compiler-starten-über-visual-studio-code&quot;&gt;TypeScript Compiler starten über Visual Studio Code&lt;/h2&gt;
&lt;p&gt;Die TypeScript-Datei wurde geschrieben, allerdings wird ja eine JavaScript-Datei zum Ausführen benötigt. Mit der Tastenkombination &lt;code class=&quot;highlighter-rouge&quot;&gt;[Strg] + [Shift] + [b]&lt;/code&gt; wird Visual Studio Code zum Builden aufgefordert. Alternativ kann auch die Command-Line mit &lt;code class=&quot;highlighter-rouge&quot;&gt;[F1]&lt;/code&gt; geöffnet werden und man Tippt &lt;code class=&quot;highlighter-rouge&quot;&gt;Build&lt;/code&gt; ein. Nun weiß Visual Studio Code nicht, was genau es machen soll. So erfolgt eine Anfrage, was genau man möchte. Hierbei wählen wir &lt;code class=&quot;highlighter-rouge&quot;&gt;TypeScript – tsconfig.json&lt;/code&gt; aus.&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/02/vscode-no-task-runner-configured.jpg&quot;&gt;&lt;img src=&quot;/images/02/vscode-no-task-runner-configured.jpg&quot; alt=&quot;Visual Studio Code - No task runner configured&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/02/vscode-select-a-task-runner-typescript.jpg&quot;&gt;&lt;img src=&quot;/images/02/vscode-select-a-task-runner-typescript.jpg&quot; alt=&quot;Visual Studio Code - Select a task runner&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;p&gt;Es wird ein neues Verzeichnis mit &lt;code class=&quot;highlighter-rouge&quot;&gt;.vscode&lt;/code&gt; erzeugt und eine tasks.json-Datei angelegt. Das angenehme an diesem Template ist, dass bereits alle relevanten Einstellungen hinterlegt sind. So können wir diese Datei wieder schließen und rufen wiederholt den Build-Vorgang mit &lt;code class=&quot;highlighter-rouge&quot;&gt;[Strg] + [Shift] + [b]&lt;/code&gt; auf. Links unten sehen wir ein rotierendes Zeichen und im File-Explorer sehen wir zwei neue Dateien zu unserer TypeScript-Datei. Einmal die generierte JavaScript-Datei und die SourceMap-Datei, die für das Debuggen nötig ist.&lt;/p&gt;

&lt;h2 id=&quot;debuggen-der-nodejs-anwendung&quot;&gt;Debuggen der Node.js-Anwendung&lt;/h2&gt;
&lt;p&gt;Zum Ausführen der Anwendung gibt es unterschiedliche Möglichkeiten. Eine Möglichkeit ist es, unabhängig von Visual Studio Code über die Konsole mit &lt;code class=&quot;highlighter-rouge&quot;&gt;node index.js&lt;/code&gt; zu starten. Nur haben wir hierbei keinen Debugging-Komfort. Deshalb nutzen wir die zweite Variante: In Visual Studio Code einfach die &lt;code class=&quot;highlighter-rouge&quot;&gt;[F5]&lt;/code&gt;-Taste zum Debuggen drücken. Auch hier weiß Visual Studio Code erstmal nicht, was er Ausführen soll. Wir wählen hierbei das &lt;code class=&quot;highlighter-rouge&quot;&gt;node.js&lt;/code&gt;-Template
 aus.&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/02/vscode-select-environment-nodejs.jpg&quot;&gt;&lt;img src=&quot;/images/02/vscode-select-environment-nodejs.jpg&quot; alt=&quot;Visual Studio Code - Select environment node.js&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;p&gt;Hier wird im &lt;code class=&quot;highlighter-rouge&quot;&gt;.vscode&lt;/code&gt;-Verzeichnis eine weitere JSON-Datei angelegt. Wichtig ist hierbei zu beachten, dass der JavaScript-Dateiname dem entspricht, was wir angelegt haben und das die Option Source Maps aktiviert ist. Ansonsten können wir nur innerhalb der JavaScript-Datei Debuggen. Anschließend drücken wir wieder die &lt;code class=&quot;highlighter-rouge&quot;&gt;[F5]&lt;/code&gt;-Taste. Der Server wurde nun ausgeführt. Wenn wir in der &lt;code class=&quot;highlighter-rouge&quot;&gt;response.write&lt;/code&gt;-Zeile die Taste &lt;code class=&quot;highlighter-rouge&quot;&gt;[F9]&lt;/code&gt; drücken, oder alternativ neben der Zeilennummer klicken, erhalten wir einen roten Breakpoint. Geht jetzt in den Browser und ruft euren Web-Server mit http://localhost:3000 auf. Visual Studio Code stoppt dann beim Breakpoint und ihr könnt alle Parameter-Werte überprüfen, wie ihr es beim Debugging anderer Hochsprachen gewohnt seid.&lt;/p&gt;

&lt;figure&gt;
	&lt;a href=&quot;/images/02/vscode-nodejs-debugging.jpg&quot;&gt;&lt;img src=&quot;/images/02/vscode-nodejs-debugging.jpg&quot; alt=&quot;Visual Studio Code - Node.js debugging&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;

&lt;p&gt;Sollte es zu Problemen kommen, liegt es meistens daran, dass man vergessen hat einmalig den TypeScript-Compiler zu starten. Überprüft daher, ob auch eure JavaScript- und SourceMap-Dateien erzeugt wurden.&lt;/p&gt;

&lt;h2 id=&quot;fazit&quot;&gt;Fazit&lt;/h2&gt;
&lt;p&gt;Visual Studio Code ist ein großartiges Tool für die Entwicklung mit Node.js und TypeScript. Mit nur wenigen Zeilen Code, haben wir einen Web-Server und ein REST Web-Service erzeugt. So ganz ohne IIS, Tomcat oder Apache HTTP Server.
Das Beispiel habe ich hier auf GitHub hinterlegt:&lt;/p&gt;

&lt;div&gt;&lt;a href=&quot;https://github.com/GregorBiswanger/VSCodeNodejsTypeScriptSample&quot; target=&quot;_blank&quot; class=&quot;btn btn-success&quot;&gt;Code on GitHub&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Konnte dir der Artikel helfen? Hast du weitere Fragen? Dann schreib mir ein Kommentar!&lt;/p&gt;

    &lt;p&gt;&lt;a href=&quot;http://www.cross-platform-blog.de/tools/nodejs/typescript/visual-studio-code-nodejs-mit-typescript-und-debugging/&quot;&gt;Visual Studio Code: Node.js mit TypeScript und Debugging&lt;/a&gt; was originally published by Gregor Biswanger at &lt;a href=&quot;http://www.cross-platform-blog.de&quot;&gt;Cross-Platform-Blog.de&lt;/a&gt; on January 27, 2017.&lt;/p&gt;
  </content>
</entry>


<entry>
  <title type="html"><![CDATA[Willkommen, schöne neue Welt…]]></title>
 <link rel="alternate" type="text/html" href="http://www.cross-platform-blog.de/allgemeines/willkommen-javascript/" />
  <id>http://www.cross-platform-blog.de/allgemeines/willkommen-javascript</id>
  <updated>2017-22-01T00:00:00-00:00</updated>
  <published>2017-01-22T00:00:00+01:00</published>
  
  <author>
    <name>Gregor Biswanger</name>
    <uri>http://www.cross-platform-blog.de</uri>
    <email>gregor.biswanger@web-enliven.de</email>
  </author>
  <content type="html">
    &lt;p&gt;…und die konnte ich schon seit über drei Jahren mit JavaScript kennenlernen. Der Schritt war nicht wirklich einfach für mich. Nach über zehn Jahren, als erfahrener .NET Experte, einfach mal den Fokus zu wechseln. Meine ersten Schritte als Entwickler in der Berufswelt ging ich mit PHP. JavaScript war damals nur ein Mittel zum Zweck. Ich war froh, wenn ich so wenig wie möglich davon nutzen musste.&lt;br /&gt;
&lt;!-- more --&gt;&lt;br /&gt;
Als spannende und ideale Plattform beflügelte mich dann .NET und C#. Zugegeben, ein paar Jahre dazwischen legte ich mit Visual Basic einen Pfad in die Windows-Entwicklung, war aber nicht wirklich glücklich damit geworden.
Microsoft mit .NET begeisterte mich so intensiv, dass ich in &lt;a href=&quot;http://www.indot.net&quot; title=&quot;INdotNET&quot; target=&quot;_blank&quot;&gt;Ingolstadt&lt;/a&gt; eine großartige Community aufbaute. Ich war international auf anderen Communities und Konferenzen unterwegs und hielt Vorträge zu meinen Erfahrungen. Ich startete die größten Community Roadshows mit mehreren tausend Besuchern. Dann schrieb ich Bücher und Artikel für Fachmagazine. Kurz gesagt, ich habe mir einen Namen mit toller Karriere bei der Microsoft Dev Welt aufgebaut.&lt;/p&gt;

&lt;h2 id=&quot;eine-neue-richtung-gehen&quot;&gt;Eine neue Richtung gehen&lt;/h2&gt;
&lt;p&gt;Die Zeit bringt Änderungen mit sich und somit auch ganz neue Kundenanforderungen. Bei zahlreichen Kundengesprächen wurde das Thema „Bring your own device“ in den Fokus gestellt. Es sitzen Manager vor mir mit Windows-, Mac- und Linux-Computern. Alle wollen in den Genuss der neuen Software-Lösung kommen und am Ende hatte immer der Browser gewonnen. Eine Lösung mit .NET konnte oft nur bedingt zum Einsatz kommen. Ich merkte wo die Stärke von diesem tollen Framework auswandert: Ins Backend und in die Cloud! Ja, es gibt dann noch Xamarin, das .NET auf die mobilen Devices bringt. Dies hatte allerdings zahlreiche Nachteile gegenüber Apache Cordova, als wir immer wieder mal Proof of Concepts ausarbeiteten.&lt;/p&gt;

&lt;p&gt;Als ich mich intensiv mit JavaScript und somit auch LISP beschäftige, konnte ich Douglas Crockfords Aussage: &lt;a href=&quot;http://www.crockford.com/javascript/javascript.html&quot; title=&quot;The World's Most Misunderstood Programming Language.&quot; target=&quot;_blank&quot;&gt;„The World’s Most Misunderstood Programming Language“&lt;/a&gt;&lt;br /&gt;
verstehen. Wir sind durch unseren Kunden Intel mit Node.js immer näher gekommen. Projekte wie Adobe Brackets, bei denen ich mitwirkte, sind komplett mit Node.js und JavaScript bestückt. Unsere Software von CleverSocial hatten wir komplett neu geschrieben von ASP.NET MVC 4/Entity Framework/SQL Server auf Node.js, Angular 2 und MongoDB. Wir lernten und spürten die Kraft der neuen JavaScript-Welt. Mein Fazit: Die JavaScript Entwicklung ist produktiver und schneller. Die Lösung am Ende läuft Cross-Platform und mit einer wahnsinnigen Geschwindigkeit. Details für den Umstieg habe ich bereits bei diesem Interview von Entwickler.de ausführlich erklärt: &lt;a href=&quot;https://entwickler.de/online/windowsdeveloper/dotnet-entwickler-nodejs-wissen-250747.html&quot; title=&quot;Was .NET-Entwickler über Node.js wissen sollten.&quot; target=&quot;_blank&quot;&gt;Was .NET-Entwickler über Node.js wissen sollten.&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;alles-aufgeben&quot;&gt;Alles aufgeben?&lt;/h2&gt;
&lt;p&gt;Überhaupt nicht! Gerade vor einer Woche noch gab ich einen Workshop zum Thema „.NET Entwicklung mit Microsoft Azure“ und hielt am Abend einen Vortrag bei der Ingolstädter .NET User Group über XAML. Wir selbst setzen intensiv auf eine Microservices-Architektur. Wenn wir eine Stärke von .NET brauchen, wird die Lösung ausgereizt. Mag es die Datenkommunikation mit dem Entity Framework zum SQL Server sein. Dann wird dazu ein ASP.NET Core Web-API mit Entity Framework Core eingesetzt oder auch auf das ältere ausgereifte Entity Framework 6. Ich werde weiterhin meine XAML Expertise-Kolumne für das Windows.Developer-Magazin schreiben. Schließlich bin ich immer noch oft genug bei Kunden zum Thema WPF unterwegs.&lt;/p&gt;

&lt;h2 id=&quot;fazit&quot;&gt;Fazit&lt;/h2&gt;
&lt;p&gt;Ich habe seit den letzten drei Jahren 70% mit JavaScript gearbeitet und nur noch 30% auf dem .NET-Stack. Ich habe viele Vorzüge von JavaScript kennengelernt und möchte hier auf meinem neuen Blog zeigen, wie einfach die JavaScript Entwicklung ist. Dazu schreibe ich allgemeines zu JavaScript/TypeScript, Tooling, Angular, Node.js, Electron, Cordova, MongoDB und vielem mehr.&lt;/p&gt;

&lt;p&gt;Hast du eventuell auch deine Richtung von einer anderen Sprache zu JavaScript gewechselt? Wenn ja, würde ich mich um ein Kommentar zu deinen Beweggründen freuen.
Ansonsten freue ich mich schon mein neues Wissen mit euch zu teilen und ich stehe auch gerne für Workshops/Trainings oder auch zur Beratung zur Verfügung. Dazu einfach eine E-Mail an mich schreiben.&lt;/p&gt;

&lt;p&gt;Ich wünsche Dir viel Spaß auf meinem neuen Blog.&lt;br /&gt;
Gregor&lt;/p&gt;


    &lt;p&gt;&lt;a href=&quot;http://www.cross-platform-blog.de/allgemeines/willkommen-javascript/&quot;&gt;Willkommen, schöne neue Welt…&lt;/a&gt; was originally published by Gregor Biswanger at &lt;a href=&quot;http://www.cross-platform-blog.de&quot;&gt;Cross-Platform-Blog.de&lt;/a&gt; on January 22, 2017.&lt;/p&gt;
  </content>
</entry>

</feed>
