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

aus GlossarWiki, der Glossar-Datenbank der Fachhochschule Augsburg
Keine Bearbeitungszusammenfassung
K (Tippfehler in "kewords" zu "keywords" und in "Unsued" zu "Unused" korrigiert)
Zeile 101: Zeile 101:


<source lang="json">
<source lang="json">
   "kewords": ["test"],
   "keywords": ["test"],
   "author": "Wolfgang Kowarschick",
   "author": "Wolfgang Kowarschick",
   "license": "CC-BY-NC-SA-4.0",
   "license": "CC-BY-NC-SA-4.0",
Zeile 214: Zeile 214:


* <code>File</code>/<code>WebStorm</code> → <code>Settings</code>/<code>Preferences</code>  → <code>Editor</code> → <code>Inspections</code>
* <code>File</code>/<code>WebStorm</code> → <code>Settings</code>/<code>Preferences</code>  → <code>Editor</code> → <code>Inspections</code>
* <code>JavaScript</code> aufklappen → <code>General</code> aufklappen → <code>Unsued global symbols</code> deselektieren
* <code>JavaScript</code> aufklappen → <code>General</code> aufklappen → <code>Unused global symbols</code> deselektieren
* <code>OK</code>
* <code>OK</code>



Version vom 9. Oktober 2017, 19:45 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: SVN-Repository

Zur Unterstützung der Entwicklung von Web-Anwendungen kann Node.js[1] eingesetzt werden: automatische Übersetzung von ECMAScript 6/7/8 (genauer ECMAScript 2015/2016/2017) 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 sehr wertvolles und universell einsetzbares Werkzeug.

Installation

Unix-Shell

Web-Entwickler verwenden unter Windows i. Allg. 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“ (https://git-for-windows.github.io/; 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 which, vi ( :-) ) etc. zur Verfügung stellt.

Unter WebStorm steht ebenfalls ein Terminal zur Verfügung, in dem Sie Kommandozeilen-Befehle absetzen können:

  • Menü am unteren Festerrand: Klick auf Terminal

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 cd <PFAD> in das Wurzelverzeichnis des Projektes wechseln, wenn Sie Befehle absetzen wollen, die sich auf ein bestimmtes Projekt beziehen.

Achtung: Unter Windows stehen Ihnen in WebStorm nur die Windows-Kommandozeilen-Befehle zur Verdügung, unter Linux und Mac können (und müssen) Sie dort Linux-Kommandozeilen-Befehle eingeben.

Node.js

Installieren Sie nun Node.js: https://nodejs.org/en/, https://nodejs.org/dist/latest01/, Version 8.x. Achten Sie darauf, dass die Option Add to PATH ausgewählt wurde.

Starten Sie ein Unix-Terminal (z. B. Mac-OS-X-Terminal, bash oder auch WebStorm: Klick auf Icon in der linken unteren Ecke → Klick auf Terminal). Öffnen Sie das Terminal, um zu testen, ob node funktioniert:

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

Wenn Node.js korrekt installiert und der Pfad mit den node-Binaries in die Systemvariable PATH eingetragen 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.

Wichtige Node.js-Pakete

Mit Hilfe von npm[2] (npm = node package manager) können beliebige Node.js-Pakete installiert werden. Viele dieser Pakte könnte man global auf dem Rechner installieren. Die globale Installation hätte zur Folge, dass jedes Projekt auf diese Pakete zugreifen kann, Pakete also nicht mehrfach installiert werden müssen.

Im Allgemeinen ist es alledings 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 Projektes 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 wir /C/mmprog/test01 als Beispielsordner. (Beachten Sie, dass in der GIT Bash wie auch im HTML-Umfeld immer Linux-Pfad-Bezeichner verwendet werden, auch unter Windows.)

Öffnen Sie nun ihr bevorzugtes Unix-Terminal und geben Sie folgenden Befehle ein:

                          # Erzeugen Sie ein neues (leeres!) Projektverzeichnis.
                          # Bitte passen Sie diesen Pfad an Ihre Gegebenheiten an.
mkdir -p /C/mmprog/test01 # Achten Sie darauf, dass es diesen Pfad vorher nicht gegeben hat.
cd /C/mmprog/test01       # Hier müssen Sie den von Ihnen zuvor definierten Pfad angeben.  
npm init -y               # Erzeugen Sie ein neues Node.js-Projekt unter Kontrolle von npm.
                          # Installieren Sie nun die Node.js-Pakete grunt (Task-Manager) 
                          # und babel (JavaScript-Transpiler) projektlokal.
npm install --save-dev grunt
ls -al                    # Sehen Sie sich an, welche Dateien und Ordner erzeugt wurden.
ls -al node_modules/.bin
                          # Damit WebStorm den Befehl 'node_modules/.bin/grunt' findet,
                          # muss noch das Grunt-Command-Line-Interface global
                          # installiert werden. 
npm install -g grunt-cli  # Mac OS X: sudo npm install -g grunt-cli
less package.json         # Sehen Sie sich den Inhalt der Konfigurationsdatei an.
                                      # Verlassen von "less": Taste "q" drücken.

Sie können das Projekt in WebStorm öffenen, um die zugehörigen Dateien mit dem WebStorm-Editor bearbeiten zu können:

  • Open bzw. File/WebStormOpen
  • Zum zuvor angelegten Testordner navigieren und diesen mit OK öffnen. Die Frage, ob Sie das Projekt im selben oder in einem neuen Fenster öffnen wollen, können Sie nach Belieben beantworten.

Sie können Ihre JavaScript-Projekt-Dateien auch mit jedem beliebigen anderen Code-Editor (Atom, Sublime, Nodepad++, Emacs etc. pp.) bearbeiten. Das liegt ganz bei Ihnen. WebStorm ist sehr angenehm zu bedienen und enthält einen kleinen Web-Server, der die Entwicklung von JavaScript-Code erleichtert. (Es gibt allerdings auch für Node.js einen einfachen HTTP-Server, der bei der Entwicklung von HTML-Anwendungen zu Testzwecken eingesetzt werden kann: https://github.com/indexzero/http-server) Das Terminalfenster von WebStorm ist auch sehr praktisch. Insbesondere Node.js-Befehle können dort direkt eingegeben werden. Unter Windows verwende ich allerdings für komplexere Aufgaben die (Git-)Bash.

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:

  "keywords": ["test"],
  "author": "Wolfgang Kowarschick",
  "license": "CC-BY-NC-SA-4.0",

Ändern Sie dagegen nicht 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 -g list # globale Node.js-Pakete
npm list    # projektlokale Node.js-Pakete

erfragen.

Sie können Pakete auch lokal löschen und dann mittels npm install wieder herstellen. Versuchen Sie es (Achtung: Die Unix-Befehle ls und rm funktionieren unter Windows nur in der Bash. In einem Windows-Terminal heißen die entsprechenden Befehle dir und del):

ls -al node_modules # Liste alle Dateien und Verzeichnisse auf,
                    # die im Ordner node_modules enthalten sind.
rm -rf node_modules # Lösche diesen Ordner samt Inhalt.
npm list
ls -al node_modules
npm install
ls -al node_modules
npm list

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
npm -g outdated # globale Node.js-Pakete

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

npm update    # projektlokale Node.js-Pakete

Bei veralteten globalen Paketen, müssen Sie das entsprechende Paket erneut installieren. Wenn beispielsweise grunt-cli veraltet ist, schreiben Sie:

npm -g install grunt-cli    # Mac OS X: sudo npm -g install grunt-cli

Wurde npm global installiert und ist veraltet, lautet der Befehl entsprechend:

npm -g install npm    # Mac OS X: sudo npm -g install npm

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 Projektes in eine Repository (SVN, Git etc.) sehr störend. Dennoch sollte man nur ein Paket wie grunt-cli, dessen einzige Aufgabe es ist, die jeweils projektlokale Version von Grunt auszuführen, 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äd das Projekt auf seinen Arbeitsrechner, öffnet ein Terminal, wechselt mittels cd ins Wurzelverzeichnis des Projektes (beim WebStorm-Terminal befindet man sich standardmäßig immer im Root-Verzeichnis des Projektes) und führt npm install aus.

Grunt

Als nächstes initialisieren Sie Grunt (https://gruntjs.com/) [3]. Grunt ist ein “JavaScript Task Runner”, also ein Programm, das Aufgaben (tasks) wie z. B. das Übersetzen von ECMAScript 2015/16/17 in ECMAScript 5.1 oder das Komprimieren von Programmdateien automatisch durchführt.

Die Initialisierung erfolgt durch die Bereitstellung zweier Dateien package.json und gruntfile.json im Root-Verzeichnis der Web-Anwendung. Die Datei package.json haben Sie schon mittels npm init erstellt.

In der Datei package.json gibt es das Attribut main. Es enthält den Namen der Konfigurationsdatei von Grunt: gruntfile.js. Diese fehlt allerdings noch. Also legen Sie sie im Wurzelverzeichnis des Projektes mit einem Texteditor Ihrer Wahl an (WebStorm: File/WebStormNewFile):

gruntfile.js

module.exports = function(grunt)
{
  // Project configuration.
  grunt.initConfig
  ({
    pkg: grunt.file.readJSON('package.json'),
  });
};

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 Änderungen an der Datei gruntfile.js jedes Mal eine Fehlermeldung zur Folge haben, wenn die Datei in ein SVN-Repository geschrieben werden soll:

  • File/WebStormSettings/PreferencesEditorInspections
  • JavaScript aufklappen → General aufklappen → Unused global symbols deselektieren
  • OK

Babel

Das Compiler „Babel“[4] wurde geschaffen, da die meisten Browser zwar ECMAScript 5.1 unterstützten[5], aber nicht die Nachfolgesprachen ECMAScript 2015, ECMAScript 2016 und ECMAScript 2017. Dies hat sich in jüngster Zeit deutlich gebessert. Die meisten Browser unterstützen diese Sprachen in der Zwischenzeit sogar besser als Babel.[6][7].

Allerdings verstehen die meisten Browser derzeit die sehr wichtigen Export- und Import-Befehle noch nicht.[8][9]

In solchen Fällen kommt Babel zum Einsatz. Babel übersetzt moderneren ECMAScript-Code in älteren ECMAScript-Code. (Da „Babel“ den Code nicht in eine maschinennähere Sprache sondern nur in eine alternative ECMAScript-Version übersetzt, sagen viele Nutzer „Transpiler“ an Stelle von „Compiler“.) Auf diese Weise wird erreicht, dass eine deutlich größere Anzahl von Browsern den Code ausführen kann.

Babel wurde selbst in ECMAScript geschrieben und liegt in Form von Node.js-Paketen vor.[10][11][12] Installieren Sie diese zunächst:

npm install --save-dev grunt babel-cli babel-preset-env grunt-babel

Nun muss Babel noch konfiguriert werden. Theoretisch könnten Sie den Übersetzer einfach von der Kommandozeile aus aufrufen (da ein Command Line Interface – CLI vorliegt). Aber das ist auf dauer etwas mühsam. Besser ist es einen Grunt-Task zu definieren, der diese Aufgabe übernimmt.

Andern Sie den Inhalt der Datei gruntfile.js:

module.exports = function(grunt)
{
  // Project configuration.
  grunt.initConfig
  ({
    pkg: grunt.file.readJSON('package.json'),

    babel:
    {
      options:
      {
        "sourceMap": true
      },
      dist:
      {
        files:
        [{
          "expand": true,
          "cwd":    "src/js",
          "src":    ["**/*.js"],
          "dest":   "web/js/",
          "ext":    ".js"
        }]
      }
    },
  });

  // Register task(s)
  grunt.loadNpmTasks("grunt-babel");

  // Default task(s).
  grunt.registerTask("default", ["babel"]);
};

Die Babel-Konfiguration bewirkt, dass alle Dateien mit der Endung .js, die sich vom Projekt-Wurzelverzeichnis <ROOT> aus gesehen im Ordner src/js oder einem darin enthaltenen Unterordner befinden, mit Hilfe von Babel übersetzt und in den Ordner <ROOT>/web/js kopiert werden. Dort erhalten sie ebenfalls die Endung .js.[13]

Mit Hilfe des Befehle grunt.loadNpmTasks("grunt-babel"); wird der Task registriert. Er kann ab sofort im Wurzelverzeichnis des Projektes mit dem Befehl grunt babel aktiviert werden. Der Befehl grunt.loadNpmTasks("grunt-babel"); sorgt dafür, dass der Task babel zur Liste der Default-Aktionen von Grunt hinzugefügt wird. Das heißt, wenn man grunt ohne Argument aufruft, wird der Babel-Task ebenfalls ausgeführt.[14]

Um Babel zu testen erzeugen Sie die Datei src/js/main.js:

  • File/WebStormNewDirectory/File

Fügen Sie folgenden EcmaScript-6-Code ein:

let evens = [0, 2, 4, 6, 8],
    odds  = evens.map(langer_parameter_name => langer_parameter_name + 1),
    pairs = evens.map(v => ({ even: v, odd: v + 1 }));

let name = "Anna";

console.log(evens);
console.log(odds);
console.log(pairs);
console.log(`Hello ${name}!`);

Diese Datei können Sie in WebStorm direkt ausführen:

  • Im Dateibaum Rechtsklick auf src/js/main.jsRun 'main.js'

Das Ergebnis sehen Sie im Konsolfester von WebStorm, da Node.js schon zu 99% ECMAScript-2015-kompatibel ist.[15]

Nun können Sie die Datei src/js/main.js mit Hilfe von Babel übersetzen. Rufen Sie einfach einmal im Terminal einen der beiden Befehle grunt babel oder einfach nur grunt im Wurzelverzeichnis des Projektes auf. Sie werden anschließend feststellen, dass ein Ordner web/js angelegt und in diesen eine Datei namens main.js eingefügt wurde. Wenn Sie sich den Inhalt dieser Datei ansehen, stellen Sie fest, dass sich sich nicht von der Datei src/js/main.js unterscheidet.

Das ist nicht weiter verwunderlich, das Babel default-mäßig gar keine Veränderungen vornimmt. Sie können sehr feingranular bestimmen, welche Übersetzungen stattfinden sollen. Erstellen Sie im Wurzelbezeichnis des Projektes die Datei .babelrc und fügen Sie folgenden Code ein:

{
  "presets": ["env"]
}

Wenn Sie jetzt den Befehl grunt noch einmal ausführen, werden Sie feststellen, dass sich src/js/main.js und web/js/main.js deutlich unterscheiden. Die Datei web/js/main.js enthält nun astreinen ECMAScript-5-Code. Diesen können Sie in WebStorm natürlich auch problemlos ausführen. Und in der Konsole werden dieselben Informationen ausgegeben wie zuvor von src/js/main.js.

Babel kann den erzeugten Code auch noch gleich komprimieren, das heißt, überflüssige Kommentare, Leerzeichen und Zeilenumbrüche entfernen, lange Variablen-, Funktions- und Parameternamen durch kurze ersetzen, wann immer dies möglich ist, etc. Dafür benötigt man die Node.js-Pakete babel-minify und babel-preset-minify.[16][17]

npm install --save-dev babel-minify babel-preset-minify

Wenn Sie nun den Inhalt der Datei .babelrc durch Folgenden Code ersetzen,

{
  "presets": ["env", "minify"]
}

wird main.jsmittels grunt babel nicht nur in ECMAScript 5 übersetzt, sondern auch noch komprimiert.

Wird dagegen

{
  "presets": ["minify"]
}

geschrieben, wird die Datei nur komprimiert, der ECMAScript-2015-Code bleibt hingegen erhalten.

Automatische Dateierzeugung mittels Grunt

Einen Nachteil hat die Lösung mit der Übersetzung von Dateien noch. Jedesmal wenn man eine Änderung an src/js/main.js vornimmt, muss man den Befehl grunt aufrufen, um web/js/main.js zu erzeugen. Das ist lästig und fehleranfällig. Besser ist es, bei jeder Änderung der Datei src/js/main.js die Datei web/js/main.js automatisch zu erstellen. Dies geht mit Hilfe des Node.js-Pakets grunt-contrib-watch[18]:

npm install --save-dev grunt-contrib-watch

Fügen Sie nun in die Datei gruntfile.js hinter dem babel-Block folgenden Block ein:

 watch:
 { 
   js:
   { files:   ['src/js/**/*.js'],
     tasks:   ['babel']
   }
 },

Anschließend müssen Sie den Watch-Task in derselben Datei noch mittels

grunt.loadNpmTasks('grunt-contrib-watch');

registrieren. Das war es schon. Wenn Sie jetzt den Watch-Task mittels grunt watch in einer Konsole im Wurzelverzeichnis des Projekts starten, wird jedesmal, wenn Sie eine Änderung an der Datei src/js/main.js vornehmen und diese speichern, wird die Datei web/js/main.js automatisch erstellt. Versuchen Sie es.

Sie können noch diverse weitere Grunt-Tasks automatisch ausführen lassen, wenn Sie sie in die Watch-Liste eintragen. Solange der Watch-Task läuft, brauchen Sie also nichts weiter zu tun, als Ihre Sourcen zu bearbeiten und die erzeugten Dateien (i. Allg. im Browser) zu testen. Sie können den Watch-Task jederzeit beenden um andere Befehle im WebStorm-Terminal auszuführen. Sie können aber auch ein zweites Terminal öffnen (z. B. eine Git-Bash) und diesen Prozess daurthaft laufen lassen, solange Sie an Ihrem Projekt arbeiten.

Quellen

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