Webtechnologien
Sommersemester 2019
Node.js
♯
♫
Node.js
<section id="nodejs" class="slide cover"><div><h2>Node.js</h2> </div></section> <section class="slide" id="installation"><div><h2>Installation</h2> <ul> <li><a href="https://nodejs.org/de/download/">Download von nodejs.org</a></li> <li>Für Windows: <a href="https://www.ionos.de/digitalguide/websites/web-entwicklung/einfuehrung-in-nodejs/#c94365">Bebilderte Installationsanleitung</a></li> </ul> </div></section> <section class="slide" id="anwendung"><div><h2>Anwendung</h2> <ul> <li>prinzipiell alles, aber häufig: <ul> <li>CLI-Programme</li> <li>Web-Server</li> <li>Desktop Apps über <a href="https://electronjs.org/">Electron</a></li> </ul> </li> </ul> <footer> <ul> <li>js runtime on top of chrome v8</li> <li>kann alles, was andere sprachen auch können: dynamische inalte erzeugen, dateien lesen, formular-daten entgegen nehmen, inhalte in datenbank speichern</li> </ul> </footer> </div></section> <section class="slide" id="anwendung---cli"><div><h2>Anwendung - CLI</h2> <p><code class="language-plaintext highlighter-rouge">generate-password.js</code></p> <pre class="highlight language-js" data-lang="js"><code><span class="kd">const</span> <span class="nx">arg</span> <span class="o">=</span> <span class="o">+</span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">||</span> <span class="mi">8</span><span class="p">;</span> <span class="kd">const</span> <span class="nx">length</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">min</span><span class="p">(</span><span class="nx">arg</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">pw</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">random</span><span class="p">().</span><span class="nf">toString</span><span class="p">(</span><span class="mi">36</span><span class="p">).</span><span class="nf">substr</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">length</span><span class="p">);</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">pw</span><span class="p">);</span> </code></pre> </div></section> <section class="slide" id="module--npm"><div><h2>Module & NPM</h2> <ul> <li>JS hatte lange kein eigenes Sprachkonstrukt (neu: <code class="language-plaintext highlighter-rouge">import</code>)</li> <li>darum globale Funktion <code class="language-plaintext highlighter-rouge">require</code></li> <li>wenige integrierte Module, z.B. <code class="language-plaintext highlighter-rouge">fs</code>, <code class="language-plaintext highlighter-rouge">http</code>, <code class="language-plaintext highlighter-rouge">os</code>, <code class="language-plaintext highlighter-rouge">path</code>, <code class="language-plaintext highlighter-rouge">url</code></li> <li>reichhaltiges Ökosystem über <a href="https://www.npmjs.com/">npm</a></li> <li>Deklaration in <code class="language-plaintext highlighter-rouge">package.json</code></li> <li>neues Projekt mit <code class="language-plaintext highlighter-rouge">npm init</code> starten</li> <li>Pakete mit <code class="language-plaintext highlighter-rouge">npm install $package-name</code> installieren</li> </ul> <footer> <ul> <li>Java: <code class="language-plaintext highlighter-rouge">import java.util.*;</code></li> <li>Node-Philosophie: small core, small modules</li> <li>hat Vor- und Nachteile (schnelle Innovation aber keine klaren Wege)</li> </ul> </footer> </div></section> <section class="slide" id="module---export"><div><h2>Module - Export</h2> <p><code class="language-plaintext highlighter-rouge">generate-password.js</code></p> <pre class="highlight language-js" data-lang="js"><code><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">(</span><span class="nx">arg</span> <span class="o">=</span> <span class="mi">8</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="kd">const</span> <span class="nx">length</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">min</span><span class="p">(</span><span class="nx">arg</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span> <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">random</span><span class="p">().</span><span class="nf">toString</span><span class="p">(</span><span class="mi">36</span><span class="p">).</span><span class="nf">substr</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">length</span><span class="p">);</span> <span class="p">};</span> </code></pre> <p><code class="language-plaintext highlighter-rouge">cli.js</code></p> <pre class="highlight language-js" data-lang="js"><code><span class="kd">const</span> <span class="nx">getPW</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">./generate-password</span><span class="dl">'</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">arg</span> <span class="o">=</span> <span class="o">+</span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">getPW</span><span class="p">(</span><span class="nx">arg</span><span class="p">));</span> </code></pre> <footer> <ul> <li>global verfügbares Objekt <code class="language-plaintext highlighter-rouge">module</code> mit property <code class="language-plaintext highlighter-rouge">exports</code></li> </ul> </footer> </div></section> <section class="slide" id="debugging"><div><h2>Debugging</h2> <ul> <li><code class="language-plaintext highlighter-rouge">console.log</code></li> <li><a href="https://github.com/GoogleChromeLabs/ndb">ndb</a></li> </ul> <footer> <ul> <li>global object</li> <li>live expressions</li> </ul> </footer> </div></section> <section class="slide" id="anwendung---web-server"><div><h2>Anwendung - Web-Server</h2> <p><code class="language-plaintext highlighter-rouge">server.js</code></p> <pre class="highlight language-js" data-lang="js"><code><span class="kd">const</span> <span class="nx">http</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">http</span><span class="dl">'</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">handler</span> <span class="o">=</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">res</span><span class="p">.</span><span class="nx">statusCode</span> <span class="o">=</span> <span class="mi">200</span><span class="p">;</span> <span class="nx">res</span><span class="p">.</span><span class="nf">setHeader</span><span class="p">(</span><span class="dl">'</span><span class="s1">Content-Type</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">text/plain</span><span class="dl">'</span><span class="p">);</span> <span class="nx">res</span><span class="p">.</span><span class="nf">end</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello World</span><span class="se">\n</span><span class="dl">'</span><span class="p">);</span> <span class="p">};</span> <span class="kd">const</span> <span class="nx">server</span> <span class="o">=</span> <span class="nx">http</span><span class="p">.</span><span class="nf">createServer</span><span class="p">(</span><span class="nx">handler</span><span class="p">);</span> <span class="nx">server</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Server started</span><span class="dl">'</span><span class="p">));</span> </code></pre> <footer> <ul> <li>Client-Server-Modell erklären</li> <li>aufgabe eines web-servers: TCP-Verbindung entgegen nehmen, auf HTTP-Anfrage mit HTTP-Antwort reagieren</li> <li><code class="language-plaintext highlighter-rouge">text/html</code></li> <li>obiges beispiel: module</li> </ul> </footer> </div></section> <section class="slide" id="express"><div><h2><a href="https://expressjs.com/de/">Express</a></h2> <ul> <li>Populärstes Web-Framework für Node.js</li> </ul> <pre class="highlight language-js" data-lang="js"><code><span class="kd">const</span> <span class="nx">express</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">();</span> <span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="c1">// app.METHOD(PATH, HANDLER)</span> <span class="nx">res</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello World!</span><span class="dl">'</span><span class="p">);</span> <span class="p">});</span> <span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Example app listening on port 3000!</span><span class="dl">'</span><span class="p">);</span> <span class="p">});</span> </code></pre> <footer> <ul> <li>erleichtert den Umgang mit Node.js HTTP und macht Entwicklung leichter</li> <li>Middleware: Funktionen die bei Ein- und Austritt durchlaufen werden</li> <li>Request-Handler: <code class="language-plaintext highlighter-rouge">request</code>, <code class="language-plaintext highlighter-rouge">response</code>, <code class="language-plaintext highlighter-rouge">next</code></li> </ul> </footer> </div></section> <section class="slide" id="express--middleware"><div><h2>Express – Middleware</h2> <pre class="highlight language-js" data-lang="js"><code><span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">((</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">before</span><span class="dl">'</span><span class="p">);</span> <span class="nf">next</span><span class="p">();</span> <span class="p">});</span> <span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">res</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello</span><span class="dl">'</span><span class="p">);</span> <span class="nf">next</span><span class="p">();</span> <span class="p">});</span> <span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">((</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">after</span><span class="dl">'</span><span class="p">);</span> <span class="nf">next</span><span class="p">();</span> <span class="p">});</span> </code></pre> </div></section> <section class="slide" id="express--middleware-1"><div><h2>Express – Middleware</h2> <pre class="highlight language-js" data-lang="js"><code><span class="kd">const</span> <span class="nx">express</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">();</span> <span class="kd">const</span> <span class="nx">requestTime</span> <span class="o">=</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">req</span><span class="p">.</span><span class="nx">requestTime</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nf">now</span><span class="p">();</span> <span class="nf">next</span><span class="p">();</span> <span class="p">};</span> <span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">requestTime</span><span class="p">);</span> <span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">res</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="s2">`Page requested at </span><span class="p">${</span><span class="nx">req</span><span class="p">.</span><span class="nx">requestTime</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span> <span class="p">});</span> <span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">);</span> </code></pre> </div></section> <section class="slide" id="express--middleware-2"><div><h2>Express – Middleware</h2> <pre class="highlight language-js" data-lang="js"><code><span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nf">static</span><span class="p">(</span><span class="dl">'</span><span class="s1">public</span><span class="dl">'</span><span class="p">));</span> </code></pre> <pre class="highlight language-js" data-lang="js"><code><span class="kd">const</span> <span class="nx">cookieParser</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">cookie-parser</span><span class="dl">'</span><span class="p">);</span> <span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nf">cookieParser</span><span class="p">());</span> <span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">((</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">req</span><span class="p">.</span><span class="nx">username</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">cookies</span><span class="p">.</span><span class="nx">username</span> <span class="o">||</span> <span class="dl">'</span><span class="s1">unbekannt</span><span class="dl">'</span><span class="p">;</span> <span class="nf">next</span><span class="p">();</span> <span class="p">});</span> </code></pre> <footer> <ul> <li>integrierte Middleware: <code class="language-plaintext highlighter-rouge">static</code> liefert Dateien aus</li> <li>Drittanbieter: <ul> <li><code class="language-plaintext highlighter-rouge">cookie-parser</code> (können auch direkt aus HTTP-Header ausgelesen werden, aber so viel leichter)</li> <li><code class="language-plaintext highlighter-rouge">body-parser</code> für Body (e.g. Formulardaten)</li> </ul> </li> <li>kurz erklären: Signed Cookies (<code class="language-plaintext highlighter-rouge">user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3</code>)</li> </ul> </footer> </div></section> <section class="slide" id="express--query-params"><div><h2>Express – Query Params</h2> <pre class="highlight language-js" data-lang="js"><code><span class="kd">const</span> <span class="nx">express</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">();</span> <span class="c1">// GET /search?q=htw+berlin</span> <span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/search</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">res</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="s2">`You searched for: </span><span class="p">${</span><span class="nx">req</span><span class="p">.</span><span class="nx">query</span><span class="p">.</span><span class="nx">q</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span> <span class="p">});</span> <span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Example app listening on port 3000!</span><span class="dl">'</span><span class="p">);</span> <span class="p">});</span> </code></pre> <footer> <ul> <li>nodemon</li> </ul> </footer> </div></section> <section class="slide" id="db-zugriff-über-htw-studi-server"><div><h2>DB-Zugriff über <a href="https://studi.f4.htw-berlin.de/www/services/mysql/">HTW-Studi-Server</a></h2> <pre class="highlight language-js" data-lang="js"><code><span class="kd">const</span> <span class="nx">mysql</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">mysql</span><span class="dl">'</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">connection</span> <span class="o">=</span> <span class="nx">mysql</span><span class="p">.</span><span class="nf">createConnection</span><span class="p">({</span> <span class="na">host</span><span class="p">:</span> <span class="dl">'</span><span class="s1">db.f4.htw-berlin.de</span><span class="dl">'</span><span class="p">,</span> <span class="na">user</span><span class="p">:</span> <span class="dl">'</span><span class="s1">beierm</span><span class="dl">'</span><span class="p">,</span> <span class="na">password</span><span class="p">:</span> <span class="dl">'</span><span class="s1">beiermPW</span><span class="dl">'</span><span class="p">,</span> <span class="na">database</span><span class="p">:</span> <span class="dl">'</span><span class="s1">_beierm__webtech</span><span class="dl">'</span><span class="p">,</span> <span class="p">});</span> <span class="nx">connection</span><span class="p">.</span><span class="nf">connect</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">connection</span><span class="p">.</span><span class="nf">query</span><span class="p">(</span><span class="dl">'</span><span class="s1">select * from users</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">result</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">users</span><span class="dl">'</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span> <span class="nx">process</span><span class="p">.</span><span class="nf">exit</span><span class="p">();</span> <span class="p">});</span> <span class="p">});</span> </code></pre> </div></section> <section class="slide" id="deployment"><div><h2>Deployment</h2> <ul> <li>mit <a href="https://zeit.co/now"><code class="language-plaintext highlighter-rouge">now</code></a></li> </ul> <pre class="highlight language-" data-lang=""><code>{ "name": "monorepo", "version": 2, "builds": [ { "src": "static/**", "use": "@now/static" }, { "src": "api/node/*.js", "use": "@now/node" } ] } </code></pre> <ul> <li>secrets + env (für db credentials)</li> </ul> </div></section> <section class="slide" id="link"><div><h2>Link</h2> <ul> <li><a href="https://www.techlounge.io/node">Video-Einführung in Node.js</a></li> <li><a href="https://www.ionos.de/digitalguide/websites/web-entwicklung/einfuehrung-in-nodejs/">1&1 Ionos – Node.js-Einführung</a></li> <li><a href="https://nodejs.dev/">Introduction to Node.js</a></li> <li><a href="https://www.w3schools.com/nodejs/">Node.js Tutorial</a> 🇬🇧 (mit MySQL)</li> <li><a href="https://github.com/i0natan/nodebestpractices#readme">The largest Node.js best practices list</a> 🇬🇧</li> </ul> </div></section>