HTML5-Tutorium: JavaScript: Entwicklungsumgebung: Node.js: Unterschied zwischen den Versionen

aus GlossarWiki, der Glossar-Datenbank der Fachhochschule Augsburg
 
(124 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
{{HTML5-Tutorium:JavaScript:Entwicklungsumgebung:Menü}}
{{HTML5-Tutorium:JavaScript:Entwicklungsumgebung:Menü}}


Zur Unterstützung der Entwicklung von Web-Anwendungen kann [[Node.js]] eingesetzt werden:
'''Musterlösung''': [https://gitlab.multimedia.hs-augsburg.de/kowa/WK_Test01 GIT-Repository]
automatische Übersetzung von EcmaScript 6 in EcmaScript 5.1, automatische Generierung der
Dokumentation, automatisches Testen der Anwendung etc.


Das heißt, auch wenn man keine [[Node.js-Server]]-Anwendung erstellt, ist Node.js ein  
Zur Unterstützung der Entwicklung von Web-Anwendungen kann [[Node.js]]<ref>Node.js: https://nodejs.org/en/</ref> eingesetzt werden.
Typische Aufgaben von Node.js sind dabei:
Generierung von statischen HTML-Seiten aus HTML-Templates, Komprimierung von HTML-/CSS-/JavaScript-Code für den Client (Browser), automatische Generierung der Dokumentation, automatisches Testen der Anwendung etc. pp.
 
Das heißt, auch wenn man keine Node.js-Server-Anwendung erstellen sollte, ist Node.js ein  
sehr wertvolles und universell einsetzbares Werkzeug.
sehr wertvolles und universell einsetzbares Werkzeug.


==Installation==
==Installation==
===Unix-Shell===
Web-Entwickler verwenden unter Windows {{iAllg}} ein Terminal, das eine [[Unix]]-[[Shell]] simuliert.
Unter Linux und Mac OS X ist es nicht notwendig, eine separate Unix-Shell zu installieren, da
diese dort sowieso schon existiert (Unix: bash, Mac OS X: terminal).
Installieren Sie „Git for Windows“ (<code>https://git-for-windows.github.io/</code>; wählen Sie bei jeder Frage die Default-Werte, außer Sie haben einen triftigen Grund, davon abzuweichen). In diesem Paket ist die „Git BASH“ enthalten.
Das ist eine Terminal-Anwendung, die eine Linux-Bash emuliert und zahlreiche nützliche Befehle wie „<code>which</code>“, „<code>[[vi]]</code>“ ( :-) ) etc. zur
Verfügung stellt.
Unter [[HTML5-Tutorium: JavaScript: Entwicklungsumgebung: WebStorm|WebStorm]] steht ebenfalls ein Terminal zur Verfügung,
in dem Sie Kommandozeilen-Befehle absetzen können:
* Klick auf Icon in der linken unteren Ecke → Klick auf <code>Terminal</code>
Wenn Sie das Web-Storm-Terminal verwenden, befinden Sie sich automatisch im Wurzelverzeichnis des zugehörigen Projektes.
Bei Im Allgemeinen müssen Sie jedoch mit Hilfe des Unix-Befehls <code>cd&nbsp;&lt;PFAD&gt;</code> in das Wurzelverzeichnis des
Projektes wechseln, wenn Sie Befehle ansetzen wollen, die sich auf ein bestimmtes Projekt beziehen.


===Node.js===
===Node.js===
Installieren Sie als Nächstes Node.js: <code>https://nodejs.org/dist/latest/</code>, Version 8.x. Diverse Versionen finden Sie unter <code>https://nodejs.org/en/download/</code>.
Installieren Sie nun Node.js: <code>https://nodejs.org/en/</code>, Version 20.x.  
Achten Sie darauf, dass die Option „<code>Add to PATH</code>“ ausgewählt wurde.


Starten Sie eine Unix-Konsole ({{zB}} <code>bash</code> oder auch WebStorm: Klick auf Icon in der linken unteren Ecke → Klick auf <code>Terminal</code>).
Starten Sie VSC neu und öffnen Sie ein Terminal, um zu testen, ob <code>node</code> funktioniert:
Öffnen Sie das Terminal, um zu testen, ob <code>node</code> funktioniert:


* Geben Sie Folgendes in die Konsole ein: <code>node -v</code>
* Geben Sie Folgendes in die Konsole ein: <code>node -v</code>  oder <code>node --version</code>


Wenn Node.js korrekt installiert und der Pfad mit den <code>node</code>-Binaries in die Systemvariable <code>PATH</code> eingetragen wurde,
Wenn Node.js korrekt installiert <!--und der Pfad mit den <code>node</code>-Binaries in die Systemvariable <code>PATH</code> eingetragen--> wurde,
sollte die Versionsnummer von <code>node</code> ausgegeben werden.
sollte die Versionsnummer von <code>node</code> ausgegeben werden.


Zeile 42: Zeile 25:
Zu Beginn mag das für eingefleischte [[Klickibunti]]-Fans ungewohnt sein, aber Sie werden sich schnell daran gewöhnen.
Zu Beginn mag das für eingefleischte [[Klickibunti]]-Fans ungewohnt sein, aber Sie werden sich schnell daran gewöhnen.


===Wichtige Node.js-Pakete===
===Ein Node.js-Test-Projekt ohne Funktionalität===
{{TBD}}
Öffnen Sie nun ein beliebiges Terminal (WebStorm-Terminal, Git Bash, Mac-OS-X-Terminal ...)
und geben Sie folgenden Befehle ein (npm = node package manager, https://www.npmjs.com/)


<source lang="bash">
Mit Hilfe von <code>npm</code><ref>npm: https://docs.npmjs.com/</ref> (node package manager) können beliebige Node.js-Pakete installiert werden.
npm install -g webpack grunt-cli jsdoc yuglify mincss coffee-script jshint
</source>


<source lang="bash">
Viele dieser Pakete könnte man global auf dem Rechner installieren.
mkdir -p /C/mmprog/test  # Projektpfad
Die globale Installation hätte zur Folge, dass jedes Projekt auf diese Pakete zugreifen könnte und damit Pakete nicht mehrfach installiert werden müssten.
cd /C/mmprog/test
Im Allgemeinen ist es allerdings besser, die Pakete für jedes Projekt separat, {{dh}} projektlokal zu installieren.
npm init -y
Die kostet zwar mehr Platz, hat aber den Vorteil, dass man für verschiedene Projekte verschiedene Pakete verwenden kann. Es kann durchaus sein, dass
npm install --save-dev webpack grunt-cli jsdoc yuglify mincss coffee-script jshint
zwei verschiedene Pakete ein drittes benötigen, doch jeweils in einer anderen Version. Außerdem stehen einem anderen Entwickler, der eine Kopie
</source>
Ihres Projekts erhält, dann sofort alle Pakete in der jeweils benötigten Version zur Verfügung.


Damit werden die wichtigsten Node.js-Pakete ''global'' (Option „<code>-g</code>“) installiert, die wir im Folgenden noch benötigen.  
Um ein neues Projekt zu erstellen, legt man zunächst einen leeren Ordner an. Es kann ein beliebiger Ordner gewählt werden.
Die globale Installation hat zur Folge, dass jedes Projekt auf diese Pakete zugreifen kann, Pakete also nicht mehrfach installiert werden müssen.
Im Folgenden wählen wird <code>/C/webprog/test01</code> als Beispielsordner verwendet. (Beachten Sie, dass in der GIT Bash wie auch im HTML-Umfeld immer Linux-Pfad-Bezeichner verwendet werden, auch unter Windows.) Unter Mac OS X/Unix sollten Sie einen Pfad in Ihren Mac/Unix-Home-Verzeichnis wählen, {{zB}}
<code>~/webprog/test01</code>. (Die Tilde <code>~</code> ist in Unix und damit auch in Mac OS X ein kurzer Alternativname für das Home-Verzeichnis. Sie können auch den vollständigen Pfad zu Ihrem Benutzerverzeichnus verwenden. Mac: <code>/Users/MACBENUTZERNAME</code>, Unix: <code>/home/UNIXBENUTZERNAME</code>).  


Als nächstes initialisieren Sie den Node-Paket-Manager „<code>npm</code>“ (https://docs.npmjs.com/) sowie Grunt (http://gruntjs.com/) .
Öffnen Sie nun das Terminal
Grunt ist '''der''' “JavaScript Task Runner”, also ein Programm, das Aufgaben (''tasks'') wie {{zB}} das Komprimieren von Programmdateien
und geben Sie folgenden Befehle ein:
durchführt.


Die Initialisierung erfolgt durch die Bereitstellung von zwei Dateien „<code>package.json</code>“
und „<code>gruntfile.json</code>“ im Root-Verzeichnis der Web-Anwendung. Eine initiale Version der <code>package.json</code> könnten Sie theoretisch mit
<code>npm init</code> erstellen. Einfacher ist es jedoch, wenn Sie die beiden Dateien von Hand erstellen und folgenden Code einfügen:
'''<code>package.json</code>''' (https://docs.npmjs.com/files/package.json)
<source lang="bash">
<source lang="bash">
{
mkdir -p /C/webprog/test01      # bzw: mkdir -p ~/webprog/test01
  "name": "hello_world_04",
                                # Erzeugen Sie ein neues (leeres!)
  "version": "1.0.0",
                                # Projektverzeichnis.
  "description": "Hello World tutorial",
                                # Bitte passen Sie diesen Pfad an
  "main": "gruntfile.js",
                                # Ihre Gegebenheiten an.
  "directories": {
    "doc": "./doc"
  },
  "dependencies": {},
  "devDependencies": {
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "svn",
    "url": "https://glossar.hs-augsburg.de/kowa/tutorium/es5/hello_world/WK_HelloWorld05"
  },
  "author": "Wolfgang Kowarschick",
  "license": "CC-BY-NC-SA-4.0"
}
</source>


Anmerkung: Diese Datei wird durch <code>npm</code> automatisch erstellt und geändert. Daher ist das Layout (welches mir nicht gefällt) vorgegeben.
cd /C/webprog/test01            # bzw: cd ~/webprog/test01
                                # Hier müssen Sie den von Ihnen
                                # zuvor definierten Pfad angeben. 
npm init -y                    # Erzeugen Sie ein neues Node.js-
                                # Projekt mit Hilfe von npm.


Hier sollten Sie natürlich nicht meinen Repositorypfad und meinen Namen einfügen, sondern jeweils Ihren. Sie können außerdem die
ls -al                          # Sehen Sie sich an, welche Dateien
Lizenz, unter die Sie Ihre Software stellen, anpassen (https://spdx.org/licenses/), wenn Sie das möchten.
                                # und Ordner erzeugt wurden.


Die meisten Attribute sind selbsterklärend. Wichtig sind für uns vor allem zwei Attribute: „<code>main</code>“ und
less package.json              # Sehen Sie sich den Inhalt der
„<code>devDependencies</code>“. Das erste enthält den Namen der Konfigurationsdatei von Grunt. Diese fehlt noch. Also: Legen Sie sie an:
                                # Konfigurationsdatei an.
                                # Verlassen von "less":
                                #  Taste "q" drücken.


'''<code>gruntfile.js</code>'''
                                # Installieren Sie nun testhalber
<source lang="javascript">
                                # zwei Node.js-Pakete projektlokal.
module.exports = function(grunt)
npm install --save-dev file-loader css-loader
{
npm i -D file-loader css-loader # hat denselben Effekt, ist aber kürzer
  // Project configuration.
  grunt.initConfig
  ({
    pkg: grunt.file.readJSON('package.json'),
  });
 
  // Load the plugin that provides the "uglify" task.
 
  // Default task(s).
};
</source>
 
Diese Datei ist noch ziemlich leer, aber das wird sich ändern.
 
Vorausschauend sollten Sie eine überflüssige WebStorm-Fehlerprüfung deaktivieren, da anderenfalls künftige Versionen
Versionen der Datei „<code>gruntfile.js</code>“ jedes Mal eine Fehlermeldung zur Folge haben, wenn die
Datei ins SVN-Repository geschrieben werden soll:
 
* <code>File</code> bzw. <code>WebStorm</code> → <code>Settings</code> bzw. <code>Preferences</code>  → <code>Editor</code> → <code>Inspections</code>
* <code>JavaScript</code> aufklappen → <code>General</code> aufklappen → <code>Unsued JavaScript / ActionScript global symbol</code> deselektieren
* <code>OK</code>
 
Spannender ist in der Datei „<code>package.json</code>“ das Attribut „<code>devDependencies</code>“ (dev = developer).
Diese enthält eine Liste von von NodeJS-Paketen, die für die Entwicklung der Web-Anwendung benötigt werden.
Fügen wir einmal das Paket „<code>ink-docstrap</code>“ in diese Liste ein.
(Diese Pakte wird nachfolgend für die Erstellung der JavaScript-Dokumentation mittels JSDoc verwendet.
Es enthält ein Theme, welches deutlich schöner ist als das Standard-JSDoc-Theme.)
 
Führen Sie folgenden Befehl im WebStorm-Terminal (oder mittels einer beliebigen anderen Shell im Wurzelverzeichnis Ihrer Web-Anwendung) aus:
 
<source lang="bash">
npm install ink-docstrap --save-dev
</source>
 
Dies bewirkt zweierlei:
 
# Das Node.js-Paket „<code> ink-docstrap</code>“ sowie diverse weitere Node.js-Pakete, die diese Paket benötigt, werden einem Projektordner namens „<code>node_modules</code>“ abgelegt.
# Das Name und die Versionsnummer des Paketes werden in das Attribut „<code>devDependencies</code>“ in der  Datei „<code>package.json</code>“ eingefügt (wegen der Option „<code>--save-dev</code>“).
 
Nun steht Ihnen der Befehl
<source lang="bash">
npm update
</source>
zur Verfügung. Mit diesem können Sie die lokal gespeicherte Versionen der im Attribut „<code>devDependencies</code>“ aufgeführte Node.js-Pakete
jederzeit auf die neueste Version aktualisieren. Sie können ein Paket auch löschen und dann mittels <code>npm update</code> (https://docs.npmjs.com/cli/update) wieder herstellen.
Versuchen Sie es:
 
<source lang="bash">
npm remove ink-docstrap
npm list
npm list
</source>
less package.json              # Durch Drücken der Taste "q" zur Konsole zurückkehren


Jetzt ist der Ordner „<code>node_modules</code>“  wieder leer.
npm install vue
 
<source lang="bash">
npm update
npm list
npm list
</source>
less package.json
 
Und jetzt enthält der wieder „<code>ink-docstrap</code>“ sowie andere dafür notwendige Pakete.
 
Sie können auch überprüfen, ob Sie in Ihrem Projekt irgendwelche veralteten Pakete benutzen (https://docs.npmjs.com/cli/outdated):
<source lang="bash">
npm outdated
</source>


Kein Ergebnis ist hier ein gutes Ergebnis!
ls -al       
ls -al node_modules            # In diesem Ordner befinden sich nicht
                                # nur file-loader und css-loader, sondern
                                # auch alle Node.js-Pakete, die von diesen
                                # beiden Paketen benutzt werden!
                                # node_modules enthält schon nach kurzer
                                # Zeit Tausende von Ordnern und Dateien!
ls -al node_modules/file-loader
ls -al node_modules/css-loader


Und natürlich funktioniert das Ganze auch für global gespeicherte Pakete:
                                # Löschen Sie nun testhalber eines
                                # der beiden Pakete.
npm uninstall --save-dev file-loader


<source lang="bash">
ls -al node_modules/file-loader
npm -g outdated
ls -al node_modules/css-loader
npm -g list
</source>


Allerdings muss man veraltete globale Pakete erneut installieren. Zum Beispiel muss <code>npm</code>
less package.json
relativ häufig aktualisiert werden (sobald  „<code>npm -g outdated</code>“ das Paket als veraltet meldet):


<source lang="bash">
rm -rf node_modules              # Löschen Sie den gesamten Ordner
npm install -g npm
                                # node_modules.
</source>
ls -al       
ls -al node_modules


==Ausschließen diverser Dateien von automatischer Speicherung und/oder Überprüfung==
less package.json
less package-lock.json


Sie sollten unbedingt verhindern das Node.js-Modulateien ins Repository geschrieben werden. Da ist, wie Sie zuvor gesehen haben,
npm i                            # Erzeugen Sie den Ordner node_modules
überflüssig und nimmt '''sehr viel''' Zeit in Anspruch, da es sich um Hunderte von Dateien handelt:
                                # neu (mit Hilfe der Informationen
                                # in den Dateien package.json und
                                # package-lock.json).
ls -al       
ls -al node_modules


* Rechtsklick im Dateibaum auf <code>node_modules</code>  → <code>Subversion</code> → <code>Ignore</code> → <code>node_modules</code>
touch .gitignore                # Datei .gitignore anlegen
* Sollte der vorangegangene Schritt schief gegangen sein (WebStorms Subversion-Tools sind in dieser Hinsicht ziemlich schlecht), müssen Sie den letzten Schritt gegebenenfalls mit einem anderen Tool bewerkstelligen. Unter Windows ist Tortoise dafür recht gut geeignet.
echo node_modules > .gitignore  # Datei .gitignore mit Inhalt füllen
less .gitignore                  # Der Ordner node_modules wird NICHT im
                                # GIT-Repository gesichert!!!
git init                        # Initialisiere das zugehörige Git-Repository
git add .                       # Füge alle Dateien des aktuellen Ordners
                                # ins Repository
git commit                      # Aktualisiere das Repository


Außerdem sollten Sie die automatische Überprüfung auf Fehler für alle Ordner ausschalten, die nicht von Ihnen stammen:
# Stellen Sie sicher, dass Sie in git Ihren "user.name" und Ihre "user.email" konfigurieren.
git config --global user.email "E-Mail-Adresse"
git config --global user.name  "Benutzername"


* Rechtsklick im Dateibaum auf „<code>node_modules</code>“ → <code>Mark Directory as</code> → <code>excluded</code>
# Melden Sie sich mit Ihrem RZ-Account zunächst im Gitlab an,
* Rechtsklick im Dateibaum auf  „<code>doc</code>“ → <code>Mark Directory as</code> → <code>excluded</code>
# damit der Remote-Zugriff auf Gitlab funktioniert:
#  https://gitlab.multimedia.hs-augsburg.de


Beide Ordner enthalten Dateien, die nicht von Ihnen stammen. Diese Dateien können Fehler und Hinweise enthalten,
# Verknüpfen Sie nun Ihr Projekt mit Gitlab.
veraltete (“deprecated”) Schnittstellen verwenden etc. (Oh ja, auch andere Programmierer machen Fehler. :-) )
# Ersetzen Sie im folgenden Befehl umbefingt ACCOUNT
Und wenn Sie diese beiden Ordner nicht als „<code>excluded markieren</code>“, prüft WebStorm bei jedem Commit die
# durch Ihren Benutzernamen:
darin enthaltenen Dateien und weist Sie auf jedes Problem hin. Das können so viele Probleme sein, dass Sie die
git remote add origin https://gitlab.multimedia.hs-augsburg.de/ACCOUNT/test01.git
Probleme in Ihren eigenen Dateien vollkommen übersehen.
                               
git remote -v                    # Zeige die aktuelle Verknüpfung an.
git push                        # Übertrage die aktuelle Version ins Repository
git push --set-upstream origin master
                                # Nur beim ersten Mal
</source>


==Automatische Generierung der Schnittstellenbeschreibung==
Sie können das Projekt in VSC öffnen, um die zugehörigen Dateien mit dem
VSC-Editor zu betrachten und gegebenenfalls auch bearbeiten:


Installieren Sie zunächst JSDoc:
* <code>File</code>/<code>Code</code> → <code>Open Folder</code>
* Zum zuvor angelegten Testordner navigieren und diesen mit <code>Ordner auswählen</code> öffnen.


* Öffnen Sie das WebStorm-Terminal.
Sie könnten Ihre JavaScript-Projekt-Dateien auch mit jedem beliebigen anderen Code-Editor (Atom, Sublime, Nodepad++, Emacs etc. pp.) bearbeiten.
* <code>npm install -g jsdoc</code> (installiert JSDoc als Node.js-Anwendung; das haben Sie eigentlich schon gemacht, aber das macht nix :-) )
Das liegt ganz bei Ihnen. Im Praktikum wird VSC verwendet. Diese IDE ist ganz angenehm zu bedienen und enthält (via Extension) einen kleinen Web-Server,  
* <code>npm install ink-docstrap</code> (installiert ein JSDoc-Theme namens „<code>docstrap</code>“ ([https://docstrap.github.io/docstrap/]); das haben Sie auch schon gemacht, aber das macht auch nix.)
der die Entwicklung von JavaScript-Code erleichtert.  


Übrigens: Es gibt auch noch andere Themes für JSDoc.
Sie sollten sich angewöhnen, in der Datei <code>package.json</code>, sofort nachdem Sie sie
erstellt haben, ein paar projektspezifische Informationen zu ergänzen, wobei Sie die Werte
natürlich an Ihre Gegebenheiten anpassen müssen:


Erstellen Sie im Projektordner  „<code>conf</code>“ eine JSON-Datei namens „<code>jsdoc.json</code>“.
<pre>
Fügen Sie in diese Datei folgenden Code ein:
"name": "test01",
"version": "0.0.1",
"description": "Dies ist ein erster Test ohne weitere Funktionalität."
...
"keywords": ["test"],
"author": "Wolfgang Kowarschick",
"license": "MIT",
...
</pre>


<source lang="javascript">
Sie können auch noch, um lästigen NPM-Warnings vorzubeugen,
{
das Repository einfügen (vor <code>devDependencies</code>), in dem sich das Projekt später befinden wird.
  "tags":
  {
    "allowUnknownTags": true
  },
  "source":
  {
    "include":        ["./src/js"],
    "includePattern": ".+\\.js$",
    "excludePattern": "doc"
  },
  "plugins":
  [],
  "templates":
  {
    "systemName":      "WK_HelloWorld04",
    "footer":          "",
    "copyright":      "Copyright © 2016 by Wolfgang Kowarschick, License <a href=\"https://creativecommons.org/licenses/by-nc-sa/4.0/\">CC-BY-NC-SA-4.0</a>",
    "navType":        "vertical",
    "theme":          "cerulean",
    "linenums":        true,
    "cleverLinks":    false,
    "monospaceLinks":  true,
    "collapseSymbols": true,
    "inverseNav":      false
  },
  "opts":
  {
    "template":    "node_modules/ink-docstrap/template",
    "encoding":    "utf8",
    "destination": "doc/jsdoc",
    "recurse":    true,
    "private":    true
  }
}
</source>


Ersetzen Sie im Attribut „<code>copyright</code>“ meinen Namen durch Ihren, denn es ist Ihr Projekt, nicht meines. :-)
{{pre|
"repository": {
  "type": "git",
  "url": "{{Git-Server}}/ACCOUNT/test01"
},
}}


In dieser Datei wird festgelegt, wie die HTML-Dokumentation des Codes, die JSDoc erstellt, aussehen soll.
Hier müssen Sie natürlich ebenfalls <code>ACCOUNT</code> durch Ihren RZ-Account ersetzen.
Insbesondere ist das Template angegeben, das zur Erstellung dieser HTML-Dokumente verwendet werden soll.
Es handelt sich um „<code>docstrap</code>“, welches wir zuvor heruntergeladen haben. Von der
Projektroot aus gesehen, befinden sich die Template-Dateien im Ordner
„<code>node_modules/ink-docstrap/template</code>“.


Weitere Konfigurationsparameter werden unter http://usejsdoc.org/about-configuring-jsdoc.html beschrieben.
Ändern Sie dagegen nie die Paketinformationen, die im Attribut <code>devDependencies</code> gespeichert sind.
Diese werden mittels <code>npm</code> verwaltet.


Sie können nun eine Dokumentation für Ihr Projekt erstellen:
Der Node-Paket-Manager <code>npm</code> ist ein sehr nützliches Hilfsprogramm,
mit dem Sie neue Node-Projekte erstellen (<code>npm init -y</code>), Pakete installieren (<code>npm install</code>) und
wieder löschen (<code>npm uninstall</code>) sowie vieles mehr machen können (Dokumentation: https://docs.npmjs.com/).


* Öffnen Sie das WebStorm-Terminal.
Wichtig ist auch der Befehl
* <code>jsdoc -c conf/jsdoc.json</code>
 
Nach kurzer Zeit sollte der Ordner „<code>doc/jsdoc</code>“ erstellt und mit Inhalten gefüllt worden sein.
Sehen Sie sich die Datei „<code>doc/jsdoc/index.html</code>“ im Browser an. Diese enthält nicht viel,
außer einem Drop-Down-Menü „<code>global</code>“, in dem die drei von Ihnen erstellen globalen Funktionen
„<code>sayHello</code>“, „<code>sayHelloOnEnter</code>“ und „<code>init</code>“ enthalten sind.
Klicken Sie auf eine dieser Funktionen.
 
===Vermeidung globaler Funktionen===
 
Die Verwendung von globalen Variablen oder Funktionen in JavaScript ist extrem gefährlich.
Wenn man eine JavaScript-Datei verwendet, in der
globale Funktionen enthalten sind, die zufälligerweise genauso heißen, wie
globale Funktionen in der eigenen JavaScript-Datei, kann man nicht beide
Dateien laden, da globale Funktionen, die in der ersten Datei enthalten sind,
durch globale Funktionen der zweiten Datei überschrieben werden.
 
Daher ist es besser, Funktionen wie „<code>sayHello</code>“, „<code>sayHelloOnEnter</code>“ und „<code>init</code>“
in ein JavaScript-Objekt einzufügen. In unseren Fall könnte man beispielsweise ein
JavaScript-Objekt „<code>main</code>“ erzeugen, dass diese drei Funktionen enthält.
Damit hat man nur noch eine globale Variable (<code>main</code>) und die Gefahr
einer zufälligen Namenskollision bei Verwendung mehrerer JavaScript-Dateien ist geringer.
 
Am besten ist es natürlich, auf globale Größen ganz zu verzichten. Dazu braucht man aber ein
Modul-System. Dieses ist für [[EcmaScript 6]] geplant ([https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import
<code>import</code>] und [https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/export <code>export</code>]), wird
aber derzeit nur von wenigen Browsern unterstützt.
 
Erserten Sie den Code in Ihrer Datei „<code>main.js</code>“ durch folgenden Code:
 
<source lang="javascript">
/** @namespace main */
var
main =
{
  /**
  * Welcomes the user of the web app by displaying a welcome message
  * that includes his name. The name is fetched from a text input field.
  */
  sayHello:
    function()
    {
      document.getElementById('text_hello').innerHTML =
        'Hello, ' + document.getElementById("input_name").value + '!';
      document.getElementById('section_form').classList.add('hidden');
      document.getElementById('section_welcome').classList.remove('hidden');
    },
 
  /**
  * An keyboard event observer. It tests whether the enter key has been pressed.
  * If so, the sayHello method is activated. Default reactions of the browser are
  * disabled.
  * @param {KeyboardEvent} p_event - A standard JavaScript keyboard event object
  *  (https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent)
  */
  sayHelloOnEnter:
    function(p_event)
    {
      if (p_event.code === 'Enter' || p_event.keyCode === 13)
      {
        p_event.preventDefault();
        p_event.stopPropagation();
        main.sayHello();
      }
    },
 
  /**
  * Initializes the web app.
  * Is to be called when the web app has been loaded completely.
  */
  init:
    function()
    {
      document.getElementById('button_submit')
              .addEventListener('click', main.sayHello);
 
      window.addEventListener('keydown', main.sayHelloOnEnter);
    }
};
 
// Call main.init, when you are ready with loading.
window.addEventListener('load', main.init);
</source>
 
Mit dem JSDoc-Kommentar „<code>@namespace main</code>“
wird angezeigt, dass die globale Variable „<code>main</code>“
als „[[Namensraum]]“ fungiert. Das heißt, <code>main</code>
enthält diverse Funktionen und evtl. andere Elemente, die irgendeinen inneren
Zusammenhang haben.
 
Wen Sie jetzt JSDoc erneut ausführen, beschreibt Ihre Dokumentation keine globale
Funktionen mehr, sondern einen Namensraum „<code>main</code>“, der die
Funktionen „<code>sayHello</code>“, „<code>sayHelloOnEnter</code>“ und „<code>init</code>“
enthält. Auf diese Funktionen kann mittels „<code>main.sayHello</code>“, „<code>main.sayHelloOnEnter</code>“
und „<code>main.init</code>“ zugegriffen werden.
 
===Erstellung der JSDoc-Dokumentation mittels Klickibunti===
 
Falls Sie die Dokumentation nicht immer über das Terminal erstellen möchten, können Sie
in WebStorm einen neuen Menüeintrag erstellen, über den Sie die Erzeugung der HTML-Dokumentation starten können.
 
Sie müssen dazu den Pfad ermitteln, unter dem Ihre <code>jsdoc</code>-Datei zu finden ist.
Unter Unix (Mac OS X, Linux, FreeBSD ...) lautet der Befehl, den Sie in ein Terminal eingeben müssen:
<source lang="bash">
<source lang="bash">
which jsdoc
npm update
</source>
Unter '''Windows''' funktioniert dieser Befehl nur in der '''Git BASH'''.
Außerdem müssen Sie unter Windows den Bash-Pfad modifizieren, damit auch Windows etwas damit anfangen kann.
Bei mir gibt dieser Befehl Folgendes aus:
<source lang="bash">
/c/Users/kowa/AppData/Roaming/npm/jsdoc
</source>
</source>
Um <code>jsdoc</code> in WebStorm aufrufen zu können, müssen Sie in diesem Pfad „<code>/c</code>“ durch
Mit diesem können Sie die lokal gespeicherte Versionen der im Attribut <code>devDependencies</code> aufgeführte Node.js-Pakete
„<code>c:</code>“ und  „<code>jsdoc</code>“ durch „<code>jsdoc.cmd</code>“ ersetzen.
jederzeit auf die neueste Version aktualisieren. Die aktuell installierten Versionen können Sie mit
(Mac-User brauchen nichts zu ändern. :-) )
 
Erstellen Sie nun den neuen WebStorm-Menü-Eintrag:
 
* <code>File</code> → <code>Settings</code> → <code>Tools</code> → <code>External Tools</code>
* Klick auf das Plus-Icon
** <code>Name</code>: <code>JSDoc</code>
** <code>Group</code>: <code>Documentation</code>
** <code>Description</code>: <code>Generates JavaScript documentation</code>
** Hacken bei allen Optionen (<code>Options</code>)
** Hacken bei allen Show-in-Optionen (<code>Show i</code>) mit Ausnahme von „<code>Search results</code>“
* <code>Program</code>: <code>c:/Users/kowa/AppData/Roaming/npm/jsdoc.cmd</code> (hier kommt Ihr zuvor ermittelter Pfad hinein)
* <code>Parameters</code>: <code>-c $ProjectFileDir$/conf/jsdoc.json</code>
* <code>Working directory</code>: <code>$ProjectFileDir$</code>
* <code>OK</code>
* <code>OK</code>
 
Nun finden Sie an mehreren Stellen in WebStorm einen neuens Menüpunkt  <code>Documentation</code> mit einem Unterpunkt <code>JSDoc</code>:
 
* Hauptmenü : <code>Tools</code> → <code>Documentation</code> → <code>JSDoc</code>
* Rechtsklick auf Datei im Projekt-Dateibaum → <code>Documentation</code> → <code>JSDoc</code>
* Rechtsklick auf Datei im Editor-Tab-Menü → <code>Documentation</code> → <code>JSDoc</code>
 
Wenn Sie auf einen dieser Unterpunkte  „<code>JSDoc</code>“ klicken, erhalten Sie entweder eine Fehlermeldung ( :-( ) oder es wird eine neue Dokumentation erstellt
({{dh}}, Sie haben alles richtig gemacht :-) ).
 
Um sicher zu gehen und um nicht mehr verwendete Dokumentationsdateien wie „<code>doc/jsdoc/global.html</code>“ zu entfernen, sollten Sie den Ordner „<code>doc/jsdoc</code>“ gemeinsam mit seinem gesamten Inhalt löschen und <code>JSDoc</code> nochmals aufrufen.
 
===Sicherung im Repository===
 
Bevor Sie weitermachen: Haben Sie Ihre aktuelle Version von <code>Hello World 04</code> schon im Repository gesichert?
 
Bevor Sie die Projekt-Dateien per ''Commit'' ins Repository übertragen, sollten Sie überprüfen,
dass der Ordner „<code>node_modules</code>“ auf der sogenannten „Ignore List“ steht (und damit nicht
ins Repository eingespielt wird):
 
* <code>Files</code> bzw. <code>WebStorm</code> → <code>Settings</code> bzw. <code>Preferences</code> → <code>Ignored Files</code>
* Wenn in dieser Liste der Ordner „<code>node_modules</code>“ nicht aufgeführt wird, fügen Sie ihn mittels des Plus-Icons ein.
 
Sie sollten allerdings den Ordner „<code>doc</code>“ zu Ihrem
Repository hinzufügen:
 
* Klick auf „<code>doc</code>“ im Dateibaum → <code>Subversion</code> → <code>Add to VCS</code>
 
Nun können Sie Ihr Projekt committen.
 
==Automatische Komprimierung von CSS- und Javascript-Dateien==
 
Nun folgt die letzte Optimierung der Anwendung. Die von Ihnen erstellten CSS- und Javascript-Dateien
enthalten viele Leerzeichen, Kommentare, „sprechende“ anstelle von kurzen Variablenbezeichnern etc.
Das ist für Sie und alle anderen Entwickler von Vorteil. Für die Übertragung der Daten zu einem
Client (Browser) bedeutet das nur unnötiges Datenvolumen. Gerade für mobile Tarife mit Volumenbegrenzung
sollten so wenig Daten wie möglich übertragen werden.
 
Glücklicherweise gibt es Tools, die bestehende CSS- oder Javascript-Dateien komprimieren (meist sogar so, dass
sich die [[Semantik]] der Dateien nicht ändert; aber wie gesagt: Auch andere Programmierer machen hin und wieder Fehler).
 
Wir verwenden die Node.js-Tools „<code>cssmin</code>“ für CSS-Dateien (https://www.npmjs.com/package/cssmin) und
„<code>UglifyJS2</code>“ für JavaScript-Dateien (https://github.com/mishoo/UglifyJS2). Gesteuert werden diese  “minimizer”
oder  “minifier” mittels dem bereits installierten ''JavaScript Task Runner'' <code>grunt</code>“.
 
Die für das Minimieren mittels Grunt notwendige Pakete wurden ebenfalls bereits installiert:


<source lang="bash">
<source lang="bash">
npm install grunt grunt-contrib-watch grunt-contrib-cssmin grunt-contrib-uglify --save-dev
npm list    # projektlokale Node.js-Pakete
</source>
</source>


Nun müssen die Aufgaben zu Komprimieren der JavaScript- und CSS-Dateien in die Konfigurationsdatei
erfragen.
eingefügt werden (vgl. http://gruntjs.com/getting-started):
 
'''<code>gruntfile.js</code>'''
<source lang="javascript">
module.exports = function(grunt)
{
  // Project configuration.
  grunt.initConfig
  ({
    pkg: grunt.file.readJSON('package.json'),
 
    cssmin:
    { options: /* https://github.com/jakubpawlowicz/clean-css */
      { roundingPrecision:  -1,
        keepSpecialComments: 1
      },
      minimize:
      { files:
        { 'web/css/main.css': ['src/css/terminal.css', 'src/css/main.css']
        }
      }
    },
 
    uglify:
    { options: /* https://github.com/gruntjs/grunt-contrib-uglify */
      { mangle:          true,
        preserveComments: function(p_node, p_comment)
                          { return /@license/.test(p_comment.value); }
      },
      minimize:
      { files: { 'web/js/main.js': ['src/js/terminal.js', 'src/js/main.js']
              }
      }
    }
  });
 
  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
 
  // Default task(s).
  grunt.registerTask('default', ['uglify', 'cssmin']);
};
</source>
 
Die Funktion  „<code>grunt.initConfig</code>“ aufgerufen und es wird ihr ein [[JavaScript-Objekt]] übergeben.
Im Attribut „<code>pkg</code>“ wird grund der Inhalt der Datei  „<code>package.json</code>“ übergeben, damit Grunt ermitteln kann, welche Pakete verfügbar sind.
Die beiden anderen Attribute „<code>cssmin</code>“ und „<code>uglify</code>“ (deren Namen frei wählbar sind), werden die beiden Minifier konfiguriert.
 
In beiden Fällen können Optionen angegeben werden, wie {{zB}}, dass CSS-Maß-Angaben nicht gerundet werden sollen (es gibt Designer, die bestehen
beim Pixelmaß auf vier Nachkommastellen) oder dass geeignete JavaScript-Variablen-Namen „durch die Mangel gedreht“ (''mangle''), also durch kürze Namen ersetzt werden sollen.
Wichtiger ist jedoch die Angabe, welche Dateien überhaupt erstellt werden und was für Sourcedaten dafür verwendet werden solle.
 
Zu jeder Datei, die erstellt wird, kann man eine ganze Liste von Sourcedateien angeben. Das hat zur Folge, dass alle  diese Sourcedateien nacheinander
komprimiert und dann in die Zieldatei eingefügt werden. Auch das ist eine Optimierung, um das Laden einer Web-Anwendung zu beschleunigen.
Eine große Datei wird per HTTP schneller übertragen als viele kleine. Künftig werden wir daher möglichst wenige komprimierte Dateien verwenden
und möglichst viele nicht-komprimierte JavaScript-Dateien in komprimierter Form nacheinander in nur eine einzige JavaScript-Datei einfügen.
 
Nach der Initialisierungsfunktion werden noch zwei weitere Funktionen aufgerufen. Mit <code>grunt.loadNpmTasks</code>
werden die Grunt-Plugins geladen, die die eigentliche Komprimierung vornehmen. Und mittels <code>grunt.loadNpmTasks</code>
wird festgelegt, welche Aufgaben standardmäßig ausgeführt werden, sobald der Befehl „<code>grunt</code>“ ausgeführt wird.
 
So, nun sollte alles funktionieren. Öffnen Sie das Web-Storm-Terminal und tippen Sie nacheinander folgende Befehle ein:


Sie können auch überprüfen, ob Sie in Ihrem Projekt irgendwelche veralteten Pakete benutzen (https://docs.npmjs.com/cli/outdated):
<source lang="bash">
<source lang="bash">
grunt cssmin
npm outdated    # projektlokale Node.js-Pakete
grunt uglify
grunt
</source>
 
Sie werden feststellen, das jedes mal bestimmte Dateien in den Ordnern „<code>web/css</code>“ oder/und „<code>web/js</code>“
erstellt werden, die mit dem Namensbestandteil „<code>min</code>“ beginnen. Sehen Sie sich die erzeugten Dateien an.
Sie enthalten denselben Code wie die Original-Dateien, nur in komprimierter (und daher für den Menschen schwer lesbarer) Form.
 
Als nächstes muss die Datei „<code>index.html</code>“ angepasst werden. Diese lädt noch die unkomprimierten Dateien aus dem
Sourceverzeichnis. Künftig soll sie die komprimierten Dateien aus dem eigentlichen Web-Ordner laden:
 
<source lang="html5">
...
<link rel="stylesheet" type="text/css" href="css/main.css"/>
...
<script type="text/javascript" src="js/main.js"></script>
</source>
</source>


Ab sofort werden nicht mehr die Sourcedateien geladen, sondern die komprimierten, durch die Minifier erstellten Dateien.
Kein Ergebnis ist hier ein gutes Ergebnis! Ansonsten sollten die die veralteten Pakete aktualisieren:
Das heißt aber für uns, dass wir bei jeder Änderung an den Sourcedateien den Befehl „<code>grunt</code>“
ausführen müssen, um die Aktualisierungen in die komprimierten Versionen der JavaScript bzw. CSS-Dateien zu übertragen.
 
Das ist lästig und geht besser.
 
==Automatische Aktualisierung der komprimierten Dateien==
 
Mit Hilfe des Node.js-Paketes „<code>grunt-contrib-watch</code>“ kann man beliebige Dateibäume überwachen,
ob sich darin bestimmte Dateien ändern. In einem derartigen Fall kann man automatisch andere Grunt Tasks ausführen lassen.
Das lässt sich ausnutzen, um nach Änderungen einer CSS-Datei oder einer JavaScript-Datei die zugehörige komprimierte
Datei automatisch neu zu erstellen.
 
Öffnen Sie das WebStorm-Terminal und laden Sie das besagte Paket:


<source lang="bash">
<source lang="bash">
npm install grunt-contrib-watch --save-dev
npm update   # projektlokale Node.js-Pakete
</source>
 
Erweitern Sie nun die Datei „<code>gruntfile.js</code>“ um einen Watch-Task:
 
<source lang="javascript">
watch:
{ css:
  { files:  ['src/css/**/*.css'],
    tasks:  ['cssmin']
  },
  js:
  { files:  ['src/js/**/*.js'],
    tasks:  ['uglify']
  },
  web:
  { files:  ['web/**/*'],
    options: { livereload: true,
              spawn:      false
            }
   }
}
</source>
 
Vergessen Sie nicht, das Plugin zu laden:
<source lang="javascript">
grunt.loadNpmTasks('grunt-contrib-watch');
</source>
 
Der Watch-Task überwacht drei verschiedene Ordner:
 
* Wann immer sich eine CSS-Datei im Ordner „<code>src/css</code>“ oder einem darin enthaltenen Unterordner ändert, wird der Task  „<code>cssmin</code>“ ausgeführt.
* Wann immer sich eine JavaScript-Datei im Ordner „<code>src/js</code>“ oder einem darin enthaltenen Unterordner ändert, wird der Task  „<code>uglify</code>“ ausgeführt.
* Wann immer sich irgendeine Datei im Web-Ordner ändert, wird eine <code>livereload</code>-Nachricht (http://livereload.com/) an einen lokalen Node-Server mit der Portnummer 35729 geschickt. (Keine Angst: Sie brauchen diesen Server nicht zu starten oder zu stoppen.)
 
Damit kann man Browser anweisen, die HTML-Dateien neu zu laden, wann immer sich etwas ändert.
Dies erfolgt entweder mit speziellen Browser-Plugins (http://livereload.com/extensions/) oder mit einem kleinen JavaScript-Hack:
Fügen Sie ans Ende der Datei „<code>main.js</code>“ folgenden Code ein:
 
<source lang="javascript">
// Enable live reloading for the WebStorm web server.
if (location.port === '63342')  // WebStorm server port
{
  var l_script = document.createElement('script');
  l_script.src = 'http://'+(location.host||'localhost').split(':')[0]+':35729/livereload.js';
  document.body.appendChild(l_script);
}
</source>
 
Dieser Code sorgt dafür, dass in eine HTML-Datei, die die Datei „<code>main.js</code>“ einbindet,
ein zusätzliches <code>script</code>-Element
<source lang="html5">
<script src="http://localhost:35729/livereload.js></script>
</source>
</source>
erstellt und in jede HTML-Datei eingefügt wird, die von einem WebStorm-Test-Server ausgeliefert wird.
(Der URI kann anstelle des Servernamens „<code>localhost</code>“ auf den echten Namen des Entwicklungsrechners enthalten, sofern
der Entwicklungsrechner einen derartigen Namen hat.)
Unter Port 35729 wird auf dem Entwicklungsrechner von <code>grunt-contrib-watch</code> der bereits erwähnte Livereload-Server gestartet und
die JavaScript-Datei „<code>livereload.js</code>“ zur Verfügung gestellt. Wenn man diese Datei in seine HTML-Datei einbindet,
aktualisiert sich die HTML-Datei fortan automatisch, sobald <code>grunt-contrib-watch</code> eine Änderung, wie {{zB}}
die Aktualisierung einer CSS-Datei, einer JavaScript-Datei, der HTML-Datei selbst oder einer anderen Datei, die von der HTML-Datei eingebunden wird,
meldet.


Allerdings wäre es falsch, <code>livereload.js</code> auf einem Live-Server ohne Testumgebung einzubinden. Dort läuft der Livereload-Server überhaupt nicht.
Da <code>npm</code> global installiert wurde (was auch sinnvoll ist), müssen Sie zum Aktualisieren von <code>npm</code> zusätlich die Option <code>-g</code> angeben:
Daher wird zunächst ermittelt, über welchen Port die aktuelle HTML-Datei von Server ausgeliefert wurde.
Üblicherweise ist dies 80, 443, 8080, 8888 oder 8443. Andere Ports werden selten verwendet.
Der Port 63342 wird mit fast absoluter Sicherheit nicht von irgendeinem realen Server verwendet. Daher verwendet ihn WebStorm.
Und daher kann mit dem Test <code>if (location.port == 63342)</code> ermittelt werden, ob die aktuelle HTML-Datei von einem WebStorm-Server
ausgeliefert wurde oder von einem anderen Server. (Die globale JavaScript-Variable „<code>location</code>“ enthält den URI, über den die HTML-Datei
vom Browser geladen wurde.)


Nun ist es an der Zeit, den <code>grunt-contrib-watch</code> zu testen. Öffnen Sie „<code>index.html</code>“ im Browser
(Rechtsklick auf <code>index.html</code> → <code>Run 'index.html'</code>) und tippen Sie dann
<source lang="bash">
grunt watch
</source>
ins WebStorm-Terminal.
Ändern Sie nun einen Eintrag in der Datei „<code>main.css</code>“ ({{zB}} <code>font-family: "Comic Sans MS";</code> :-) ).
Wenn Sie diese Änderungen speichern (Strg-S, Apfel-S), sollten Sie zweierlei Reaktionen bemerken.
Zum einem wird ins Terminal die Meldung
<source lang="bash">
<source lang="bash">
>> File "web/css/main.css" changed.
npm -v                                # Gib die aktuelle Version von npm aus.
npm install -g agentkeepalive --save  # ist evtl. notwendig, um einen Fehler zu beheben
npm -g install npm                    # Mac OS X: sudo npm -g install npm
npm -v                                # Gib die aktuelle Version von npm aus.
</source>
</source>
geschrieben und zum anderen ändert sich das Layout der HTML-Datei im Browser, da die aktualisierte CSS-Datei
Das Tool <code>npm</code> kann sich also selbst aktualisieren. :-)
automatisch vom Browser nachgeladen wurde.


Wenn Sie die Designsünde  „Comic Sans MS“ rückgängig machen, ändert sich die Datei kurz darauf auch im Browser wieder.
Node.js-Pakete können, wie wir gesehen haben, mittels der NPM-Option <code>-g</code> auch global gespeichert werden, werden aber normalerweise projektlokal abgelegt.
Durch die projektlokale Speicherung von Node.js-Paketen bläht sich ein Projekt sehr stark auf. Es enthält dann
meist mehrere Tausend Dateien, auch wenn das eigentliche Projekt nur aus ein paar wenigen Dateien besteht. Dies ist vor allem beim Speichern eines derartigen Projekts in eine Repository ([[Git]], [[SVN]] etc.)
sehr störend. Dennoch sollte man nur ein Paket wie <code>npm</code>, dessen einzige Aufgabe es ist, die Node.js-Pakete selbst zu verwalten, global installieren.


Das ist schon ziemlich „cool“, hat aber noch einen Schönheitsfehler: Das WebStorm-Terminal kann nicht anderweitig genutzt werden, solange
Um das Repository-Problem zu vermeiden, muss man die Speicherung von Node.js-Bibliotheken im [[Repository]] ausschließen und
der Grunt-Watcher läuft. Um dieses Problem zu beheben, wird ein WebStorm-Startup-Task definiert, der den Watcher bei jedem
diese Dateien bei Bedarf automatisch von den entsprechenden Servern herunterladen. Wie das geht, haben wir gerade gesehen:
Programmstart von WebStorm automatisch in einem eigenständigen [[Task]] startet. Der Watcher läuft dann, solange WebStorm geöffnet ist.  
Man lädt das Projekt auf seinen Arbeitsrechner, öffnet ein Terminal, wechselt mittels <code>cd</code> ins Wurzelverzeichnis des Projekts
Für seine Ausgaben steht im ein eigenes Ausgabefenster zur Verfügung. Was will man mehr?
(beim VSC-Terminal befindet man sich standardmäßig immer im Root-Verzeichnis des Projekts) und führt
<code>npm install</code> bzw. <code>npm i</code> aus. Dies ist viel effizienter, als Node.js-Module zwischen verschiedenen Speicherbereichen hin- und her zu kopieren.


* <code>File</code> → <code>Settings</code> → <code>Tools</code> → <code>Startup Tasks</code> → <code></code>
=== Zugriff auf Gitlab mittels SSH ===
* Klick auf grünes Plus-Icon → <code>Add New Configuration</code> → <code>Grunt.js</code>
** Name: <code>Watch</code>
** Gruntfile: <code>.../HelloWorld04/gruntfile.js</code> (sollte bereits korrekt eingetragen sein)
** Tasks: <code>watch</code>
** Der Node-Interpreter und das Node.js-Paket <code>grunt-cli</code> sollten ebenfalls bereits korrekt eingetragen sein.
* <code>OK</code> (Unter „<code>Run configuration</code>“ sollte jetzt „<code>Watch</code>“ stehen.)
* <code>OK</code>


Wenn Sie nun WebStorm neu starten, sollte und der Menüzeile am unteren Fensterrand ein Tabulator mit dem Namen „<code>Run</code>“ vorhanden sein.
Öffnen Sie ein Bash-Terminal und erzeugen Sie ein SSH-Key-Paar:
Wenn Sie das zugehörige Fenster öffnen sollte dort Folgendes stehen:


<source lang="bash">
<source lang="bash">
grunt watch
ssh-keygen -t ed25519 -C "gitlab.multimedia.hs-augsburg.de"
Running "watch" task
Waiting...
</source>
</source>


Sobald Sie irgendeine Änderung an eine <code>web</code>- oder <code>src</code>-Datei der Web-App vornehmen, werden alle im Watcher definierten Aktionen
Fügen Sie den '''öffentlichen''' Schlüssel in Gitlab ein.
(automatische Komprimierung bzw. Neuladen des HTML-Datei im Browser) automatisch ausgeführt. Der Watcher läuft solange, bis Sie WebStorm beenden.
Öffnen Sie die Url
Es erfolgt dabei sogar noch eine Sicherheitsabfrage, on Sie den Prozess „<code>Watch</code>“ beenden wollen.
<!-- „<code></code>“ npm install grunt-contrib-watch --save-dev-->
 
==JSHint==
 
Ein weiteres sehr interessantes Tool, das den JavaScript-Entwickler unterstützt, ist JSHint (http://jshint.com/).
JSHint analysiert vorhandenen JavaScript-Code und weist auf Fehler und Strukturprobleme hin.
 
Installieren Sie zunächst die zugehörigen Node.js-Pakete:
 
<source lang="bash">
<source lang="bash">
npm install grunt-contrib-jshint jshint-stylish --save-dev
https://gitlab.multimedia.hs-augsburg.de/
</source>
</source>
 
loggen Sie sich ein und navigieren Sie zu den SSH-Settings
Anschließend fügen Sie einen JSHit-Task in die Datei „<code>gruntfile.js</code>“ ein.
 
<source lang="javascript">
jshint:
{
  all: ['gruntfile.js', 'src/**/*.js'],
 
  options:
  {
    esversion: 5,
    eqeqeq:    true,
    eqnull:    true,
    browser:  true,
    reporter:  require('jshint-stylish')
  }
}
</source>
 
 
Nun können alle vom Entwickler erstellten JavaScript-Dateien analysiert werden. Geben Sie dazu im
WebStorm-Terminal einfach folgenden Befehl ein:
 
<source lang="bash">
<source lang="bash">
grunt jshint
https://gitlab.multimedia.hs-augsburg.de/-/profile/keys
(Icon rechts oben → Preferences → SSH Keys)
</source>
</source>
Fügen Sie den Text aus der Datei <code>id_ed25519.pub</code> in das
Textfeld <code>Key</code> und klicken Sie <code>Add key</code>.


Gut ist es, wenn JSHint mit der Meldung <code>v No problems</code> antwortet.
Nun können Sie in Ihrer Bash den SSH-Zugang überprüfen. (Denken Sie daran,
Ansonsten sollten Sie in Ihrem Code die von JSHint gemeldeten Probleme beheben.
dass der Gitlab-Server derzeit nur per VPN zugänglicg ist.)
 
Machen Sie ruhig mal die Probe auf's Exempel: Ersetzen Sie  
in der Datei „<code>main.js</code>“ „<code>=</code><code>==</code>“ durch „<code>==</code>“ und lassen Sie
danach JSHint laufen. Dann sollte JSHint Folgendes melden:


<source lang="bash">
<source lang="bash">
Expected '===' and instead saw '=='.
mkdir -p ~/tmp
cd ~/tmp
ssh -T git@gitlab.multimedia.hs-augsburg.de
# Antwort: Welcome to GitLab, @ACCOUNT!
git clone git@gitlab.multimedia.hs-augsburg.de:ACCOUNT/hello_world_01.git
# Reaktion: Ihr Hello-World-01-Repository wird heruntergeladen.
ls -al hello_world_01
</source>
</source>


Damit wird ausgedrückt, dass ein nicht-strikter Gleichheitstest verwendet wurde,
== Fortsetzung des Tutoriums ==
aber ein strikter Gleichheitstest verwendet werden sollte. Der Grund ist, dass
nicht-strikte Fehlertests manchmal subtile Fehler zur Folge haben, die
nur sehr schwer zu entdecken sind.


JSHint kennt zahlreiche Optionen, die festlegen, welche Fehler und Probleme gemeldet
Sie sollten nun [[HTML5-Tutorium: JavaScript: Hello World|Hello-World-Tutorium]] bearbeiten.
werden sollen und welche nicht: http://jshint.com/docs/options/.
Hier muss jeder Programmierer seinen eigenen Stil finden.
 
Folgende Optionen wurden im obigen Beispiel verwendet:
 
<dl>
</dt><code>esversion: 5</code></dt>
<dd>Des sollen die Regeln von [[EcmaScript 5]] beachtet werden.</dd>
</dt><code>eqeqeq: true</code></dt>
<dd>Es sollt stets ein strikter Gleichheitstest verwendet werden.</dd>
</dt><code>eqnull</code></dt>
<dd>Der nicht-strikte Gleichheitstest <code>... == null</code> ist allerdings erlaubt.
</dd>
</dt><code>browser: true</code></dt>
<dd>Globale Variable sollte man eigentlich grundsätzlich nicht verwenden.
Mit dieser Option werden für die globalen Variablen, die die Browser bereitgestellt werden
(<code>document</code>, <code>window</code>, <code>console</code> etc) Ausnahmen definiert.</dd>
</dl>
 
'''Anmerkung''': Wäre der nicht-strikte Gleichheitstest auf „<code>null</code>“ nicht erlaubt, müsste man
in viele Fällen „
<source lang="javascript">
if (... === null || ...=== undefined)
</source>
schreiben. Geben Sie folgende Befehle einfach mal in die Konsole Ihres Web-Browsers ein
(Firefox: <code>Strg-Shift-K</code>, Opera und Chrome: <code>Strg-Shift-I</code> → <code>Console</code>):
 
<source lang="javascript">
var a;
var b = null;
 
// Strikte Gleichheitstests
console.log(a === null);                    /* -> false */
console.log(a === undefined);                /* -> true  */
console.log(b === null);                    /* -> true  */
console.log(b === undefined);                /* -> false */
console.log(a === null || a === undefined);  /* -> true  */
console.log(b === null || b === undefined);  /* -> true  */
 
// Nicht-strikte Gleichheitstests
console.log(a == null);                      /* -> true  */
console.log(a == undefined);                /* -> true  */
console.log(b == null);                      /* -> true  */
console.log(b == undefined);                /* -> true  */
</source>
 
Zum Abschluss können Sie entweder einen WebStorm-Menü-Eintrag hinzufügen, um den JSHint jederzeit per Klickibunti starten zu können.
Oder Sie fügen gleich „<code>jslint</code>“ in die Watch-Liste ein, damit jede Änderung sofort analysiert und Fehler sofort angezeigt werden:
 
'''<code>gruntfile.js</code>'''
<source lang="javascript">
watch:
{ ...
  js:
  { files:  ['src/js/**/*.js'],
    tasks:  ['uglify', 'jshint']
  },
  ...
}
</source>
 
Allerdings kann JSHint manchmal nerven. :-) Dagegen helfen dann spezielle Kommentare im JavaScript-Code, die
JSHint anweisen für die Prüfung des nachfolgenden Codes spezielle Optionen zu benutzen, die dann {{iAllg}}
eine etwas weniger strenge Überprüfung des Codes zur Folge haben (http://jshint.com/docs/).
 
 
 
[[Kategorie:Kapitel:Web-Programmierung]]
[[Kategorie:Web-Programmierung-HowTo]]
[[Kategorie:Praktikum:MMProg]]


==Quellen==
==Quellen==
<references/>
<references/>
<ol>
<ol>
<li value="1"> {{Quelle|Kowarschick, W.: Multimedia-Programmierung}}</li>
<li value="3">{{Quelle|Kowarschick (WebProg)}}</li>
</ol>
</ol>
<noinclude>[[Kategorie: HTML5-Tutorium: JavaScript: Entwicklungsumgebung]][[Kategorie: HTML5-Beispiel]][[Kategorie:Kapitel:Multimedia-Programmierung:Beispiele]]</noinclude>
[[Kategorie: HTML5-Tutorium: JavaScript: Entwicklungsumgebung]]
[[Kategorie:Kapitel:Multimedia-Programmierung:Beispiele]]
[[Kategorie:Praktikum:MMProg]]
[[Kategorie:Web-Programmierung-HowTo]]

Aktuelle Version vom 19. März 2024, 15:50 Uhr

Dieser Artikel erfüllt die GlossarWiki-Qualitätsanforderungen nur teilweise:

Korrektheit: 3
(zu größeren Teilen überprüft)
Umfang: 2
(wichtige Fakten fehlen)
Quellenangaben: 2
(wichtige Quellen fehlen)
Quellenarten: 3
(gut)
Konformität: 5
(ausgezeichnet)

Vorlesung WebProg

Inhalt | Visual Studio Code | Node.js

Musterlösung: GIT-Repository

Zur Unterstützung der Entwicklung von Web-Anwendungen kann Node.js[1] eingesetzt werden. Typische Aufgaben von Node.js sind dabei: Generierung von statischen HTML-Seiten aus HTML-Templates, Komprimierung von HTML-/CSS-/JavaScript-Code für den Client (Browser), automatische Generierung der Dokumentation, automatisches Testen der Anwendung etc. pp.

Das heißt, auch wenn man keine Node.js-Server-Anwendung erstellen sollte, ist Node.js ein sehr wertvolles und universell einsetzbares Werkzeug.

Installation

Node.js

Installieren Sie nun Node.js: https://nodejs.org/en/, Version 20.x.

Starten Sie VSC neu und öffnen Sie ein Terminal, um zu testen, ob node funktioniert:

  • Geben Sie Folgendes in die Konsole ein: node -v oder node --version

Wenn Node.js korrekt installiert wurde, sollte die Versionsnummer von node ausgegeben werden.

Sie werden feststellen, das Node.js zum Großteil über Terminal-Befehle gesteuert wird. Zu Beginn mag das für eingefleischte Klickibunti-Fans ungewohnt sein, aber Sie werden sich schnell daran gewöhnen.

Ein Node.js-Test-Projekt ohne Funktionalität

Mit Hilfe von npm[2] (node package manager) können beliebige Node.js-Pakete installiert werden.

Viele dieser Pakete könnte man global auf dem Rechner installieren. Die globale Installation hätte zur Folge, dass jedes Projekt auf diese Pakete zugreifen könnte und damit Pakete nicht mehrfach installiert werden müssten. Im Allgemeinen ist es allerdings besser, die Pakete für jedes Projekt separat, d. h. projektlokal zu installieren. Die kostet zwar mehr Platz, hat aber den Vorteil, dass man für verschiedene Projekte verschiedene Pakete verwenden kann. Es kann durchaus sein, dass zwei verschiedene Pakete ein drittes benötigen, doch jeweils in einer anderen Version. Außerdem stehen einem anderen Entwickler, der eine Kopie Ihres Projekts erhält, dann sofort alle Pakete in der jeweils benötigten Version zur Verfügung.

Um ein neues Projekt zu erstellen, legt man zunächst einen leeren Ordner an. Es kann ein beliebiger Ordner gewählt werden. Im Folgenden wählen wird /C/webprog/test01 als Beispielsordner verwendet. (Beachten Sie, dass in der GIT Bash wie auch im HTML-Umfeld immer Linux-Pfad-Bezeichner verwendet werden, auch unter Windows.) Unter Mac OS X/Unix sollten Sie einen Pfad in Ihren Mac/Unix-Home-Verzeichnis wählen, z. B. ~/webprog/test01. (Die Tilde ~ ist in Unix und damit auch in Mac OS X ein kurzer Alternativname für das Home-Verzeichnis. Sie können auch den vollständigen Pfad zu Ihrem Benutzerverzeichnus verwenden. Mac: /Users/MACBENUTZERNAME, Unix: /home/UNIXBENUTZERNAME).

Öffnen Sie nun das Terminal und geben Sie folgenden Befehle ein:

mkdir -p /C/webprog/test01      # bzw: mkdir -p ~/webprog/test01
                                # Erzeugen Sie ein neues (leeres!) 
                                # Projektverzeichnis.
                                # Bitte passen Sie diesen Pfad an 
                                # Ihre Gegebenheiten an.

cd /C/webprog/test01            # bzw: cd ~/webprog/test01
                                # Hier müssen Sie den von Ihnen 
                                # zuvor definierten Pfad angeben.  
npm init -y                     # Erzeugen Sie ein neues Node.js-
                                # Projekt mit Hilfe von npm.

ls -al                          # Sehen Sie sich an, welche Dateien 
                                # und Ordner erzeugt wurden.

less package.json               # Sehen Sie sich den Inhalt der
                                # Konfigurationsdatei an.
                                # Verlassen von "less": 
                                #   Taste "q" drücken.

                                # Installieren Sie nun testhalber
                                # zwei Node.js-Pakete projektlokal.
npm install --save-dev file-loader css-loader 
npm i -D file-loader css-loader # hat denselben Effekt, ist aber kürzer
npm list
less package.json               # Durch Drücken der Taste "q" zur Konsole zurückkehren

npm install vue
npm list
less package.json 

ls -al        
ls -al node_modules             # In diesem Ordner befinden sich nicht 
                                # nur file-loader und css-loader, sondern 
                                # auch alle Node.js-Pakete, die von diesen
                                # beiden Paketen benutzt werden!
                                # node_modules enthält schon nach kurzer
                                # Zeit Tausende von Ordnern und Dateien!
ls -al node_modules/file-loader
ls -al node_modules/css-loader

                                # Löschen Sie nun testhalber eines 
                                # der beiden Pakete.
npm uninstall --save-dev file-loader

ls -al node_modules/file-loader
ls -al node_modules/css-loader

less package.json

rm -rf node_modules              # Löschen Sie den gesamten Ordner
                                 # node_modules.
ls -al        
ls -al node_modules

less package.json
less package-lock.json

npm i                            # Erzeugen Sie den Ordner node_modules
                                 # neu (mit Hilfe der Informationen
                                 # in den Dateien package.json und 
                                 # package-lock.json).
ls -al        
ls -al node_modules

touch .gitignore                 # Datei .gitignore anlegen
echo node_modules > .gitignore   # Datei .gitignore mit Inhalt füllen
less .gitignore                  # Der Ordner node_modules wird NICHT im 
                                 # GIT-Repository gesichert!!!
git init                         # Initialisiere das zugehörige Git-Repository
git add .                        # Füge alle Dateien des aktuellen Ordners
                                 # ins Repository
git commit                       # Aktualisiere das Repository

# Stellen Sie sicher, dass Sie in git Ihren "user.name" und Ihre "user.email" konfigurieren.
git config --global user.email "E-Mail-Adresse"
git config --global user.name  "Benutzername"

# Melden Sie sich mit Ihrem RZ-Account zunächst im Gitlab an,
# damit der Remote-Zugriff auf Gitlab funktioniert:
#   https://gitlab.multimedia.hs-augsburg.de

# Verknüpfen Sie nun Ihr Projekt mit Gitlab.
# Ersetzen Sie im folgenden Befehl umbefingt ACCOUNT 
# durch Ihren Benutzernamen:
git remote add origin https://gitlab.multimedia.hs-augsburg.de/ACCOUNT/test01.git
                                 
git remote -v                    # Zeige die aktuelle Verknüpfung an.
git push                         # Übertrage die aktuelle Version ins Repository
git push --set-upstream origin master
                                 # Nur beim ersten Mal

Sie können das Projekt in VSC öffnen, um die zugehörigen Dateien mit dem VSC-Editor zu betrachten und gegebenenfalls auch bearbeiten:

  • File/CodeOpen Folder
  • Zum zuvor angelegten Testordner navigieren und diesen mit Ordner auswählen öffnen.

Sie könnten Ihre JavaScript-Projekt-Dateien auch mit jedem beliebigen anderen Code-Editor (Atom, Sublime, Nodepad++, Emacs etc. pp.) bearbeiten. Das liegt ganz bei Ihnen. Im Praktikum wird VSC verwendet. Diese IDE ist ganz angenehm zu bedienen und enthält (via Extension) einen kleinen Web-Server, der die Entwicklung von JavaScript-Code erleichtert.

Sie sollten sich angewöhnen, in der Datei package.json, sofort nachdem Sie sie erstellt haben, ein paar projektspezifische Informationen zu ergänzen, wobei Sie die Werte natürlich an Ihre Gegebenheiten anpassen müssen:

"name": "test01",
"version": "0.0.1",
"description": "Dies ist ein erster Test ohne weitere Funktionalität."
...
"keywords": ["test"],
"author": "Wolfgang Kowarschick",
"license": "MIT",
...

Sie können auch noch, um lästigen NPM-Warnings vorzubeugen, das Repository einfügen (vor devDependencies), in dem sich das Projekt später befinden wird.

"repository": {
  "type": "git",
  "url": "https://gitlab.multimedia.hs-augsburg.de/ACCOUNT/test01"
},

Hier müssen Sie natürlich ebenfalls ACCOUNT durch Ihren RZ-Account ersetzen.

Ändern Sie dagegen nie die Paketinformationen, die im Attribut devDependencies gespeichert sind. Diese werden mittels npm verwaltet.

Der Node-Paket-Manager npm ist ein sehr nützliches Hilfsprogramm, mit dem Sie neue Node-Projekte erstellen (npm init -y), Pakete installieren (npm install) und wieder löschen (npm uninstall) sowie vieles mehr machen können (Dokumentation: https://docs.npmjs.com/).

Wichtig ist auch der Befehl

npm update

Mit diesem können Sie die lokal gespeicherte Versionen der im Attribut devDependencies aufgeführte Node.js-Pakete jederzeit auf die neueste Version aktualisieren. Die aktuell installierten Versionen können Sie mit

npm list    # projektlokale Node.js-Pakete

erfragen.

Sie können auch überprüfen, ob Sie in Ihrem Projekt irgendwelche veralteten Pakete benutzen (https://docs.npmjs.com/cli/outdated):

npm outdated    # projektlokale Node.js-Pakete

Kein Ergebnis ist hier ein gutes Ergebnis! Ansonsten sollten die die veralteten Pakete aktualisieren:

npm update    # projektlokale Node.js-Pakete

Da npm global installiert wurde (was auch sinnvoll ist), müssen Sie zum Aktualisieren von npm zusätlich die Option -g angeben:

npm -v                                # Gib die aktuelle Version von npm aus.
npm install -g agentkeepalive --save  # ist evtl. notwendig, um einen Fehler zu beheben
npm -g install npm                    # Mac OS X: sudo npm -g install npm
npm -v                                # Gib die aktuelle Version von npm aus.

Das Tool npm kann sich also selbst aktualisieren. :-)

Node.js-Pakete können, wie wir gesehen haben, mittels der NPM-Option -g auch global gespeichert werden, werden aber normalerweise projektlokal abgelegt. Durch die projektlokale Speicherung von Node.js-Paketen bläht sich ein Projekt sehr stark auf. Es enthält dann meist mehrere Tausend Dateien, auch wenn das eigentliche Projekt nur aus ein paar wenigen Dateien besteht. Dies ist vor allem beim Speichern eines derartigen Projekts in eine Repository (Git, SVN etc.) sehr störend. Dennoch sollte man nur ein Paket wie npm, dessen einzige Aufgabe es ist, die Node.js-Pakete selbst zu verwalten, global installieren.

Um das Repository-Problem zu vermeiden, muss man die Speicherung von Node.js-Bibliotheken im Repository ausschließen und diese Dateien bei Bedarf automatisch von den entsprechenden Servern herunterladen. Wie das geht, haben wir gerade gesehen: Man lädt das Projekt auf seinen Arbeitsrechner, öffnet ein Terminal, wechselt mittels cd ins Wurzelverzeichnis des Projekts (beim VSC-Terminal befindet man sich standardmäßig immer im Root-Verzeichnis des Projekts) und führt npm install bzw. npm i aus. Dies ist viel effizienter, als Node.js-Module zwischen verschiedenen Speicherbereichen hin- und her zu kopieren.

Zugriff auf Gitlab mittels SSH

Öffnen Sie ein Bash-Terminal und erzeugen Sie ein SSH-Key-Paar:

ssh-keygen -t ed25519 -C "gitlab.multimedia.hs-augsburg.de"

Fügen Sie den öffentlichen Schlüssel in Gitlab ein. Öffnen Sie die Url

https://gitlab.multimedia.hs-augsburg.de/

loggen Sie sich ein und navigieren Sie zu den SSH-Settings

https://gitlab.multimedia.hs-augsburg.de/-/profile/keys
(Icon rechts oben → Preferences → SSH Keys)

Fügen Sie den Text aus der Datei id_ed25519.pub in das Textfeld Key und klicken Sie Add key.

Nun können Sie in Ihrer Bash den SSH-Zugang überprüfen. (Denken Sie daran, dass der Gitlab-Server derzeit nur per VPN zugänglicg ist.)

mkdir -p ~/tmp
cd ~/tmp 
ssh -T git@gitlab.multimedia.hs-augsburg.de
# Antwort: Welcome to GitLab, @ACCOUNT!
git clone git@gitlab.multimedia.hs-augsburg.de:ACCOUNT/hello_world_01.git
# Reaktion: Ihr Hello-World-01-Repository wird heruntergeladen.
ls -al hello_world_01

Fortsetzung des Tutoriums

Sie sollten nun Hello-World-Tutorium bearbeiten.

Quellen

  1. Kowarschick (WebProg): Wolfgang Kowarschick; Vorlesung „Web-Programmierung“; Hochschule: Hochschule Augsburg; Adresse: Augsburg; Web-Link; 2024; Quellengüte: 3 (Vorlesung)