|
|
| (101 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) |
| Zeile 1: |
Zeile 1: |
| {{HTML5-Tutorium:JavaScript:HelloWorld:Menü}} | | {{HTML5-Tutorium:JavaScript:HelloWorld:Menü}} |
| '''Musterlösung''': [https://glossar.hs-augsburg.de/beispiel/tutorium/es5/hello_world/WK_HelloWorld05/index.html <code>index.html</code>]
| |
| ([https://glossar.hs-augsburg.de/beispiel/tutorium/es5/hello_world/WK_HelloWorld05/ SVN-Repository]; nach Download: <code>npm update</code>)
| |
| ==Anwendungsfälle (Use Cases)==
| |
| Gegenüber dem [[HTML5-Tutorium:_JavaScript:_Hello_World_03|dritten Teil des Tutoriums]]
| |
| ändern sich die die Anwendungsfälle nicht. Die Anwendung leistet also genau dasselbe wie zuvor.
| |
|
| |
|
| In diesem Teil des Tutoriums geht es darum, die Anwendung zu verbessern, so dass sie schneller ausgeliefert werden kann.
| | '''Musterlösung'''<br/> |
| Außerdem wird die Entwicklungsarbeit mit Hilfe von Automatisierungstools erleichtert.
| | [https://glossar.hs-augsburg.de/beispiel/tutorium/2025/wk_hello_world/wk_hello_world_06/web/index.html <code>index.html</code>] ([https://validator.nu/?doc=https%3A%2F%2Fglossar.hs-augsburg.de%2Fbeispiel%2Ftutorium%2F2025%2Fwk_hello_world%2Fwk_hello_world_06%2Fweb%2Findex.html HTML validate], [https://css-validator.org/validator?uri=https%3A%2F%2Fglossar.hs-augsburg.de%2Fbeispiel%2Ftutorium%2F2025%2Fwk_hello_world%2Fwk_hello_world_06%2Fweb%2Findex.html&profile=css21&usermedium=all&warning=1&lang=de CSS validate], [https://pagespeed.web.dev/analysis?url=https%3A%2F%2Fglossar.hs-augsburg.de%2Fbeispiel%2Ftutorium%2F2025%2Fwk_hello_world%2Fwk_hello_world_06%2Fweb%2Findex.html Google PageSpeed])<br/> |
| | [{{Git-Server}}/kowa/wk_hello_world_06.git Git-Repository] |
|
| |
|
| ==Erstellen eines neuen Projektes== | | == Anwendungsfälle (Use Cases) == |
| | Gegenüber dem [[HTML5-Tutorium:_JavaScript:_Hello_World_05|dritten, vierten und fünften Teil des Tutoriums]] |
| | ändern sich die die Anwendungsfälle nicht. Die Anwendung leistet also genau dasselbe wie zuvor. |
|
| |
|
| Erstellen Sie ein neues Projekt „<code>HelloWorld04</code>“ und legen Sie dieses in Ihrem Repository ab.
| | In diesem Teil des Tutoriums geht es darum, den CSS-Code „[[DRY]] zu machen“. |
| Kopieren Sie anschließend alle Dateien aus dem dritten Teil des Tutoriums, passen Sie den Titel in der HTML-Datei an und committen Sie abermals.
| |
|
| |
|
| ==Erstellen einer Ordnerstruktur== | | == Erstellen eines neuen Projekts == |
|
| |
|
| Grundsätzlich gilt auch bei der Programmierung: Ordnung ist das halbe Leben.
| | Erstellen Sie ein neues Projekt <code>hello_world_06</code> als Fork von <code>hello_world_05</code>. |
|
| |
|
| Web-Anwendungen werden sehr schnell sehr groß. Also sollte man sich eine geeignete Ordnerstruktur überlegen.
| | == CSS-Erweiterungen == |
| Üblicherweise legt man CSS-Dateien in einen Ordner namens „<code>css</code>“ und JavaScript-Dateien in einen Ordner namens
| |
| „<code>js</code>“ oder „<code>lib</code>“. Sollten es viele CSS- und/oder JavaScript-Dateien werden,
| |
| legt man im entsprechenden Ordner geeignete Unterordner an.
| |
|
| |
|
| Legen Sie im Root-Verzeichnis Ihres Projektes folgende Ordner an:
| | CSS bietet heute dieselbe Funktionalität wie Transpiler ([[SASS]], [[Less]] etc.), die früher verwendet wurden, um fehlende Funktionalität in CSS zu integrieren. Ich werde in diesem Semester CSS an Stelle von SCSS einsetzen, so wie es von vite empfohlen wird: |
| * <code>web</code>: Der Inhalt dieses Ordners kommt später auf einen echten Web-Server.
| |
| * <code>src</code>: Dieser Ordner enthält die unkomprimierten CSS- und JavaScript-Dateien.
| |
| * <code>doc</code>: Dieser Ordner enthält die Projektdokumentation.
| |
| * <code>conf</code>: Dieser Ordner enthält Projektkonfigurationsdateien mit Ausnahme zweier zentraler Node.js-Dateien.
| |
| Legen Sie innerhalb der Ordner „<code>web</code>“ und „<code>src</code>“ jeweils zwei weitere Ordner an: „<code>css</code>“ sowie „<code>js</code>“ .
| |
|
| |
|
| Öffnen Sie im Editorbereich die Datei „<code>index.html</code>“ und verschieben sie in den Ordner „<code>src</code>“.
| | ''Because Vite targets modern browsers only, it is recommended to use native CSS variables with PostCSS plugins that implement CSSWG drafts (e.g. postcss-nesting) and author plain, future-standards-compliant CSS.'' (https://vite.dev/guide/features) |
| Verschieben sie anschließend die Dateien „<code>main.css</code>“ und „<code>main.js</code>“
| |
| in die passenden Ordner „<code>src/css</code>“ bzw. „<code>src/js</code>“. Sie werden feststellen, dass die Verweise in den Link- und Script-Elementen der
| |
| Datei „<code>index.html</code>“ automatisch angepasst werden. Verschieben Sie nun die Datei „<code>index.html</code>“ in den Ordner „<code>web</code>“.
| |
|
| |
|
| Das Ergebnis dieser Aktion ist, dass Ihre Web-Anwendung nicht mehr im Root-Verzeichnis des Projektes liegt, sondern (sauber strukturiert) in zwei Unterordnern.
| | Eine ganz wesentliche Erweiterung ist die Möglichkeit Konstanten zu definieren. |
| Daher ist es möglich, im Root-Verzeichnis des Projektes weitere projektspezifische Ordner und Dateien anzulegen wie „<code>conf</code>“ und „<code>doc</code>“,
| | Auch die Möglichkeit, Werte zu berechnen, gibt es in der Zwischenzeit (SCSS: <code>math</code>, CSS: <code>calc</code>). Es ist jetzt auch möglich CSS-Elemente zu verschachteln. |
| die später nicht auf den Web-Server, auf dem die Anwendung schließlich laufen soll, kopiert werden. Auch der Ordner „<code>src</code>“ existiert nur
| | Das heißt, die Bedeutung von SCSS, Less etc. schwindet. |
| in der Entwicklungsumgebung, lediglich der Inhalt des Web-Ordners ist für den Liveserver bestimmt.
| |
|
| |
|
| ==Laden der CSS- und der JavaScript-Dateien== | | == CSS-Konstanten == |
|
| |
|
| Eine Web-Anwendung funktioniert nur – wie Sie bereits erfahren haben –, wenn nicht nur die HTML-Datei, sondern auch die zugehörigen | | Eine ganz wesentliche Erweiterung ist die Möglichkeit Konstanten zu definieren, da man damit CSS-Code [[DRY]] formulieren kann. |
| CSS- und JavaScript-Dateien geladen werden. Allerdings gibt es dabei ein Problem: Die CSS- und JavaScript-Dateien werden im Laufe der | |
| Zeit immer zahlreicher und/oder größer. Diese Dateien zu laden, dauert seine Zeit.
| |
|
| |
|
| In der aktuellen Version der Web-Anwendung stehen diese Verweise auf diese Dateien im <code>head</code>-Bereich des Dokuments.
| | Wenn eine Konstante definiert wurde, kann man |
| Dieser wird vollständig geladen, bevor der <code>body</code>-Bereich eingelesen wird. Das heißt aber, dass der Browser keine Inhalte des HTML-Dokuments
| | im übrigen CSS-Code mittels <code>var</code> darauf zugreifen (und nicht etwa mittels <code>const</code>, :-( ) |
| darstellen kann, solange er die JavaScript- und CSS-Dateien lädt. Wenn dies zu lange dauert, verliert der Besucher die Geduld und verlässt die Seite
| |
| vorzeitig.
| |
|
| |
|
| Besser wäre es daher andersherum vorzugehen: Es wird zuerst der <code>body</code>-Bereich geladen und dann die JavaScript- und die CSS-Dateien.
| | <syntaxhighlight lang="CSS"> |
| Im Falle von JavaScript ist das durchaus sinnvoll, aber im Falle von CSS hat das den Effekt, dass der Browser keine Layout-Vorgaben erhalten hat,
| | :root |
| wenn er mit dem [[Rendern]] der Seite beginnt. Also verwendet er die browserspezifischen Defaultwerte. Das heißt, die Seite sieht zunächst
| | { --font-family-serif: "Times New Roman", Times, serif; } |
| ganz anders aus, als vom Designer geplant. Wenn dann die CSS-Dateien geladen wurden, wird die Seite erneut gerendert und verändert ihr Aussehen.
| |
| Auch das ist verwirrend und wirkt unprofessionell.
| |
|
| |
|
| Was also machen?
| | p |
| | { font-family: var(--font-family-serif); } |
|
| |
|
| ===CSS-Dateien===
| | label |
| Für CSS-Dateien empfiehlt Google ernsthaft, die Link-Element ganz ans Ende der HTML-Datei zu stellen, also '''nach''' dem
| | { font-family: var(--font-family-serif); } |
| schließenden <code>html</code>-Tag.
| | </syntaxhighlight> |
| Damit das Problem mit dem falschen Layout nicht auftritt, sollen wichtige CSS-Befehle direkt – {{dh}} als CSS-Befehle innerhalb eines
| |
| <code>style</code>-Elements – in die HTML-Datei eingefügt
| |
| werden.<ref>{{Quelle|Google (Web)}}, Kapitel „CSS-Bereitstellung optimieren“, https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery</ref>
| |
|
| |
|
| Von beiden Vorschlägen rate ich dringend ab. Der erste Vorschlag ist nicht [[HTML]]-konform, ja noch nicht einmal [[SGML]]-konform. Es mag sein,
| | Auch die Möglichkeit, Werte zu berechnen, gibt es in der Zwischenzeit (SCSS: <code>math</code>, CSS: <code>calc</code>). |
| dass diverse Browser diese Syntax verstehen, korrekt ist sie trotzdem nicht. Der zweite Vorschlag hat zur Folge, dass Struktur (HTML) und Layout (CSS)
| | Das heißt, die Bedeutung von SCSS, Less etc. schwindet. In diesem Semester verwende ich nicht mehr SCSS, sondern nur noch CSS. |
| vermischt werden. Dies war einer der Kardinalfehler von frühen HTML-Versionen aus der Zeit, bevor es das CSS-Format gab. '''Tun Sie das nicht.'''
| |
|
| |
|
| Gehen Sie so vor, wie es unter [[Multimedia-Programmierung: Best Practices#CSS|Multimedia-Programmierung: Best Practices]] beschrieben ist.
| | Fügen Sie <code>"config"</code> als Abkürzung für <code>"./src/css/_config.css"</code> in die Datei <code>vite.config.js</code> ein. |
|
| |
|
| In unserer Anwendung haben wir bislang alles richtig gemacht, bis auf die fehlende automatische Komprimierung.
| | <syntaxhighlight lang="javascript"> |
| Diese wird weiter unten beschrieben.
| | ... |
| | resolve: |
| | { alias: |
| | { ... |
| | 'config.css': fileURLToPath(new URL('./src/css/_config.css', import.meta.url)), |
| | ... |
| | } |
| | } |
| | ... |
| | </syntaxhighlight> |
|
| |
|
| ===JavaScript-Dateien===
| | In der Datei <code>_config.css</code> werden Konstanten definiert, die von allen anderen CSS-Dateien verwendet werden können und sollen. |
|
| |
|
| Für JavaScript-Dateien empfiehlt Google ebenfalls, diese nicht schon zu Beginn zu laden.<ref>{{Quelle|Google (Web)}}, Kapitel „CSS-Bereitstellung optimieren“, https://developers.google.com/speed/docs/insights/BlockingJS</ref> Dieser Vorschlag ist sehr sinnvoll.
| | Das heißt, das DRY-Prinzip „Konstanten gehören nicht in den Code, sondern in Konfigurationsdateien“ wird ab sofort beachtet. |
|
| |
|
| Entfernen Sie das <code>script</code>-Element aus dem HTML-Header-Bereich und fügen Sie es vor dem schließenden <code>body</code>-Tag ein:
| | Wenn man künftig am Layout einen Zeichensatz, eine Farbe, einen Hintergrund oder Ähnliches ändern will, |
| | reicht es, die entsprechenden Konstanten anzupassen und schon erzeugt Vite automatisch aktualisiere |
| | CSS-Dateien. |
|
| |
|
| <source lang="html5">
| | Durch den CSS-Import-Befehl ist es möglich, CSS-Dateien zu modularisieren. |
| ...
| | Der Underscore <code>_</code> am Beginn des Dateinamens deutet an, dass diese CSS-Datei nur von anderen CSS-Dateien |
| <script type="text/javascript" src="../src/js/main.js"></script>
| | aber nicht von HTML- oder JavaScript-Dateien importiert werden sollte. |
|
| |
|
| </body> | | '''<code>src/css/_config.css</code>''' |
| </source> | | <syntaxhighlight lang="CSS"> |
| | :root |
| | { --background-color: #C5EFFC; |
|
| |
|
| ===Node.js===
| | --font-family-sans: Verdana, Helvetica, sans-serif; |
| | --font-family-serif: "Times New Roman", Times, serif; |
| | |
| | --font-size-base: 3vw; |
| | --font-size-factor: 1.25; /* cmp. https://type-scale.com/ */ |
| | |
| | --font-size-h5: calc(pow(var(--font-size-factor),1)*var(--font-size-base)); |
| | --font-size-h4: calc(pow(var(--font-size-factor),2)*var(--font-size-base)); |
| | --font-size-h3: calc(pow(var(--font-size-factor),3)*var(--font-size-base)); |
| | --font-size-h2: calc(pow(var(--font-size-factor),4)*var(--font-size-base)); |
| | --font-size-h1: calc(pow(var(--font-size-factor),5)*var(--font-size-base)); |
| | |
| | --font-size-p: calc(pow(var(--font-size-factor),0)*var(--font-size-base)); |
| | --font-size-p-large: calc(pow(var(--font-size-factor),2)*var(--font-size-base)); |
| | |
| | --font-size-small: calc(pow(var(--font-size-factor),-1)*var(--font-size-base)); |
| | } |
| | </syntaxhighlight> |
| | In dieser CSS-Datei werden folgende modernen CSS-Konstrukte verwendet: |
|
| |
|
| Dieses Tutorium befasst sich zwar nicht mit der Erstellung von Node.js-Anwendungen, aber trotzdem benötigen wir
| | * Definition von Konstanten (die teilweise per Berechnung ermittelt werden) |
| Node, da für die Komprimierung von Dateien und das automatische Erstellen von JavaScript-Dokumentationen
| | * Mathematische Berechnungen: <code>calc</code> |
| derartige Anwendungen zum Einsatz kommen.
| |
|
| |
|
| Installieren Sie zunächst Node.js: <code>https://nodejs.org/en/</code>, Version 6.x. Diverse Versionen finden Sie unter https://nodejs.org/en/download/.
| | Konstanten starten in CSS mit zwei Minuszeichen. Sobald eine Konstante definiert wurde, |
| Achten Sie darauf, dass die Option „<code>Add to PATH</code>“ ausgewählt wurde.
| | kann sie in allen weiteren CSS-Konstrukten verwendet werden. In CSS stehen einen Operatoren zur Verfügung wie |
| | <code>+</code>, <code>-</code>, <code>*</code> und <code>/</code>, um Maße zu berechnen. Es gibt |
| | weitere Operatoren zum Vergleichen von Zahlen und Maßen sowie zur Berechnung von Strings und booleschen Werten: |
| | https://sass-lang.com/documentation/operators.<ref>https://sass-lang.com/documentation/operators</ref> |
|
| |
|
| Starten Sie WebStorm neu und öffnen Sie das Terminal, um zu testen, ob <code>node</code> funktioniert:
| | Die Datei <code>_config.css</code> kann nun mit Hilfe des CSS-Befehls <code>@import 'config.css';</code> (ohne Underscore und ohne <code>.css</code>, wegen des zuvor eingeführten Vite-Aliases) |
| | in die anderen beiden CSS-Dateien eingefügt werden. |
|
| |
|
| * Klick auf Icon in der linken unteren Ecke → <code>Terminal</code>
| | === PostCSS === |
| * Geben Sie Folgendes ins Terminal ein: <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,
| | Der Inhalt der Datei <code>_config.css</code> wird defaultmäßig an den Browser ausgeliefert, obwohl sie nur CSS-Konstanten enthält. |
| sollte die Versionsnummer von <code>node</code> ausgegeben werden.
| | Beim Einsatz vom SCSS werden Konstanten vom SCSS-Präprozessor auf dem Server während des Build-Prozesses durch ihre Werte ersetzt. |
| | In CSS muss dies defaultmäßig der Browser übernehmen. Es gibt allerdings ein PostCSS-Plugin [https://www.npmjs.com/package/postcss-var-replace/v/1.0.0 postcss-var-replace], das diese Ersetzungen ebenfalls während des Build-Prozesses vornimmt. Dieses kann man in die Vite-Konfiguration integrieren: |
|
| |
|
| Sie werden feststellen, das Node.js zum Großteil über Konsolbefehle gesteuert wird.
| | Laden sie das Pluging <code>postcss-var-replace</code>: |
| Zu Beginn mag das für eingefleischte [[Klickibunti]]-Fans ungewohnt sein, aber Sie werden sich schnell daran gewöhnen.
| |
|
| |
|
| '''Tipp'''<br/>
| | <syntaxhighlight lang="bash"> |
| Profis verwenden unter Windows lieber ein Terminal, dass eine [[Unix]]-[[Shell]] simuliert.
| | npm i -D postcss-var-replace |
| (Unter Linux und Mac OS X ist das nicht notwendig. Dort läuft sowieso schon eine UNIX-Shell.)
| | </syntaxhighlight> |
|
| |
|
| Installieren Sie „Git for Windows“ (https://git-for-windows.github.io/). In diesem Paket ist die „Git BASH“ enthalten.
| | Anschließend aktivieren Sie es in <code>vite.config.js</code> |
| 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.
| |
|
| |
|
| Öffnen Sie nun ein beliebiges Terminal (WebStorm-Terminal, Git Bash, Mac-OS-X-Terminal ...)
| | <syntaxhighlight lang="javascript"> |
| und geben Sie folgenden Befehl ein (npm = node package manager, https://www.npmjs.com/)
| | import { postcssVarReplace } from 'postcss-var-replace'; |
|
| |
|
| <source lang="bash">
| | ... |
| npm install -g bower grunt-cli jsdoc yuglify mincss coffee-script jshint
| |
| </source>
| |
|
| |
|
| Damit werden die wichtigsten Node.js-Pakete ''global'' (Option „<code>-g</code>“) installiert, die wir im Folgenden noch benötigen, evtl. implizit.
| | export default |
| Die globale Installation hat zur Folge, dass jedes Projekt auf diese Pakete zugreifen kann, Pakete also nicht mehrfach installiert werden.
| | { ... |
| | | css: |
| Nun müssen wir den Node-Paket-Manager „<code>npm</code>“ (https://docs.npmjs.com/) sowie Grunt (http://gruntjs.com/) initialisieren.
| | { postcss: |
| Grunt ist '''der''' “JavaScript Task Runner”, also ein Programm, das Aufgaben (''tasks'') wie {{zB}} das Komprimieren von Programmdateien
| | { plugins: |
| durchführt.
| | [ postcssVarReplace(), |
| | | ], |
| 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">
| |
| { | |
| "name": "hello_world_04",
| |
| "version": "1.0.0",
| |
| "description": "Hello World Tutorium",
| |
| "main": "gruntfile.js",
| |
| "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_HelloWorld04"
| |
| },
| |
| "author": "Wolfgang Kowarschick",
| |
| "license": "CC-BY-NC-SA-4.0"
| |
| } | | } |
| </source> | | </syntaxhighlight> |
|
| |
|
| Anmerkung: Diese Datei wird durch <code>npm</code> automatisch erstellt und geändert. Daher ist das Layout (welches mir nicht gefällt) vorgegeben.
| | Der Import-Befehl hat ab sofort erst dann einen Effekt, wenn in den anderen Dateien auf diese Konstanten zugegriffen wird. |
| | Aber er schadet auch nicht, wenn auf keine der dort definierten Konstanten zugegriffen wird. Der Import-Befehl selbst |
| | taucht ebenso wenig in den generierten CSS-Dateien auf, wie die Konstantendefinitionen. Der PostCSS-Transpiler ersetzt Konstanten in CSS-Definitionen durch ihren jeweiligen Wert. |
|
| |
|
| Hier sollten Sie natürlich nicht meinen Repositorypfad und meinen Namen einfügen, sondern jeweils Ihren. Sie können außerdem die
| | Sie können nun beispielsweise in der Datei <code>head.css</code> die Konstante <code>--background-color</code> |
| Lizenz anpassen (https://spdx.org/licenses/), unter die Sie Ihre Software stellen, wenn Sie das möchten.
| | verwenden. In dem daraus durch den Build-Befehl <code>npm run build</code> erzeugten CSS-Style-Element steht weiterhin der Farbwert <code>#C5EFFC</code>; |
|
| |
|
| Die meisten Attribute sind selbsterklärend. Wichtig sind für uns vor allem zwei Attribute: „<code>main</code>“ und
| | '''<code>src/css/head.css</code>''' |
| „<code>devDependencies</code>“. Das erste enthält den Namen der Konfigurationsdatei von Grunt. Diese fehlt noch. Also: Legen Sie sie an
| | <syntaxhighlight lang="CSS"> |
| (und vergessen Sie nicht, Ihren Namen anstelle meines Namens einzufügen):
| | @import 'config.css'; |
|
| |
|
| '''<code>gruntfile.js</code>'''
| | body |
| <source lang="javascript">
| | { background-color: var(--background-color); } |
| /**
| | |
| * @author Wolfgang Kowarschick <kowa@hs-augsburg.de>
| | .hidden |
| * @see http://gruntjs.com/getting-started
| | { display: none; } |
| * | | </syntaxhighlight> |
| * Created on 2016/09/28.
| |
| */
| |
|
| |
|
| module.exports = function(grunt)
| | Die Datei <code>body.css</code> ist deutlich umfangreicher. Daher wird der zugehörige CSS-Code |
| {
| | ja auch erst dynamisch gemeinsam mit der Datei <code>web/js/main.js</code> geladen. |
| // Project configuration.
| |
| grunt.initConfig
| |
| ({
| |
| pkg: grunt.file.readJSON('package.json'),
| |
| });
| |
|
| |
|
| // Load the plugin that provides the "uglify" task.
| | '''<code>src/css/body.css</code>''' |
| | <syntaxhighlight lang="CSS"> |
| | @import 'config.css'; |
|
| |
|
| // Default task(s). | | html |
| };
| | { height: 100%; |
| </source>
| | width: 100%; |
| | display: table; |
| | } |
|
| |
|
| Diese Datei ist noch ziemlich leer, aber das wird sich ändern.
| | body |
| | { display: table-cell; |
| | text-align: center; |
| | vertical-align: middle; |
| | font-size: var(--font-size-base); |
| | font-family: var(--font-family-sans); |
| | } |
|
| |
|
| Vorausschauend sollten Sie eine überflüssige WebStorm-Fehlerprüfung deaktivieren, da anderenfalls künftige Versionen
| | h1 |
| Versionen der Datei „<code>gruntfile.js</code>“ jedes Mal eine Fehlermeldung zur Folge haben, wenn die
| | { padding: 0; |
| Datei ins SVN-Repository geschrieben werden soll:
| | margin: 0; |
| | font-size: var(--font-size-h1); |
| | } |
|
| |
|
| * <code>File</code> bzw. <code>WebStorm</code> → <code>Settings</code> bzw. <code>Preferences</code> → <code>Editor</code> → <code>Inspections</code>
| | p, label |
| * <code>JavaScript</code> aufklappen → <code>General</code> aufklappen → <code>Unsued JavaScript / ActionScript global symbol</code> deselektieren
| | { font-family: var(--font-family-serif); |
| * <code>OK</code>
| | font-size: var(--font-size-p); |
| | } |
|
| |
|
| Spannender ist in der Datei „<code>package.json</code>“ das Attribut „<code>devDependencies</code>“ (dev = developer).
| | label, input |
| Diese enthält eine Liste von von NodeJS-Paketen, die für die Entwicklung der Web-Anwendung benötigt werden.
| | { width: 10em; |
| Fügen wir einmal das Paket „<code>ink-docstrap</code>“ in diese Liste ein.
| | font-size: 100%; |
| (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.)
| | display: inline-block; |
| | box-sizing: border-box; |
| | margin: 0.5ex; |
| | } |
|
| |
|
| Führen Sie folgenden Befehl im WebStorm-Terminal (oder mittels eine beliebigen anderen Shell im Wurzelverzeichnis Ihrer Web-Anwendung) aus:
| | label |
| | | { text-align: right; |
| <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
| | #section_form |
| <source lang="bash">
| | { text-align: center; |
| npm update
| | margin-left: auto; |
| </source>
| | margin-right: auto; |
| 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">
| | h1 |
| npm remove ink-docstrap
| | { margin-bottom: 0.5ex; } |
| npm list
| |
| </source>
| |
| | |
| Jetzt ist der Ordner „<code>node_modules</code>“ wieder leer.
| |
| | |
| <source lang="bash">
| |
| npm update
| |
| npm list
| |
| </source>
| |
| | |
| 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!
| |
| | |
| Und natürlich funktioniert das Ganze auch für global gespeicherte Pakete:
| |
| | |
| <source lang="bash">
| |
| npm -g outdated
| |
| npm -g list
| |
| </source>
| |
| | |
| Allerdings muss man veraltete globale Pakete erneut installieren. Zum Beispiel muss <code>npm</code>
| |
| relativ häufig aktualisiert werden (sobald „<code>npm -g outdated</code>“ das Paket als veraltet meldet):
| |
| | |
| <source lang="bash">
| |
| npm install -g npm
| |
| </source>
| |
| | |
| ==Ausschließen diverser Dateien von automatischer Speicherung und/oder Überprüfung==
| |
| | |
| Sie sollten unbedingt verhindern das Node.js-Modulateien ins Repository geschrieben werden. Da sit, wie Se zuvor gesehen haben,
| |
| überflüssig und nimmt '''sehr viel''' Zeit in Anspruch, da es sich um Hunderte von Dateien handelt:
| |
| | |
| * Rechtsklick im Dateibaum auf <code>node_modules</code> → <code>Subversion</code> → <code>Ignore</code> → <code>node_modules</code>
| |
| * 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.
| |
| | |
| Außerdem sollten Sie die automatische Überprüfung auf Fehler für alle Ordner ausschalten, die nicht von Ihnen stammen:
| |
| | |
| * Rechtsklick im Dateibaum auf „<code>node_modules</code>“ → <code>Mark Directory as</code> → <code>excluded</code>
| |
| * Rechtsklick im Dateibaum auf „<code>doc</code>“ → <code>Mark Directory as</code> → <code>excluded</code>
| |
| | |
| Beide Ordner enthalten Dateien, die nicht von Ihnen stammen. Diese Dateien können Fehler und Hinweise enthalten,
| |
| veraltete (“deprecated”) Schnittstellen verwenden etc. (Oh ja, auch andere Programmierer machen Fehler. :-) )
| |
| Und wenn Sie diese beiden Ordner nicht als „<code>excluded markieren</code>“, prüft WebStorm bei jedem Commit die
| |
| darin enthaltenen Dateien und weist Sie auf jedes Problem hin. Das können so viele Probleme sein, dass Sie die
| |
| Probleme in Ihren eigenen Dateien vollkommen übersehen.
| |
| | |
| ==Automatische Generierung der Schnittstellenbeschreibung==
| |
| | |
| Installieren Sie zunächst JSDoc:
| |
| | |
| * Öffnen Sie das WebStorm-Terminal.
| |
| * <code>npm install -g jsdoc</code> (installiert JSDoc als Node.js-Anwendung; das haben Sie eigentlich schon gemacht, aber das macht nix :-) )
| |
| * <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.)
| |
| | |
| Übrigens: Es gibt auch noch andere Themes für JSDoc.
| |
| | |
| Erstellen Sie im Projektordner „<code>conf</code>“ eine JSON-Datei namens „<code>jsdoc.json</code>“.
| |
| Fügen Sie in diese Datei folgenden Code ein:
| |
| | |
| <source lang="javascript">
| |
| {
| |
| "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. :-)
| |
|
| |
| In dieser Datei wird festgelegt, wie die HTML-Dokumentation des Codes, die JSDoc erstellt, aussehen soll.
| |
| 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.
| |
|
| |
| Sie können nun eine Dokumentation für Ihr Projekt erstellen:
| |
|
| |
| * Öffnen Sie das WebStorm-Terminal.
| |
| * <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>greet</code>“, „<code>greetOnEnter</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>greet</code>“, „<code>greetOnEnter</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.
| |
| */
| |
| greet:
| |
| 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 greet 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)
| |
| */
| |
| greetOnEnter:
| |
| function(p_event)
| |
| {
| |
| if (p_event.code === 'Enter' || p_event.keyCode === 13)
| |
| {
| |
| p_event.preventDefault();
| |
| p_event.stopPropagation();
| |
| main.greet();
| |
| }
| |
| },
| |
|
| |
| /**
| |
| * 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.greet);
| |
|
| |
| window.addEventListener('keydown', main.greetOnEnter);
| |
| }
| |
| };
| |
|
| |
| // 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 erneu ausführen, beschreibt Ihre Dokumentation keine globale
| |
| Funktionen mehr, sondern einen Namensraum „<code>main</code>“, der die
| |
| Funktionen „<code>greet</code>“, „<code>greetOnEnter</code>“ und „<code>init</code>“
| |
| enthält. Auf diese Funktionen kann mittels „<code>main.greet</code>“, „<code>main.greetOnEnter</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">
| |
| which jsdoc
| |
| </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>
| |
| Um <code>jsdoc</code> in WebStorm aufrufen zu können, müssen Sie in diesem Pfad „<code>/c</code>“ durch
| |
| „<code>c:</code>“ und „<code>jsdoc</code>“ durch „<code>jsdoc.cmd</code>“ ersetzen.
| |
| (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">
| | #section_hello |
| npm install grunt grunt-contrib-watch grunt-contrib-cssmin grunt-contrib-uglify --save-dev
| | { p |
| </source>
| | { font-size: var(--font-size-p-large) !important; } |
| | |
| Nun müssen die Aufgaben zu Komprimieren der JavaScript- und CSS-Dateien in die Konfigurationsdatei
| |
| 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:
| |
| | |
| <source lang="bash">
| |
| grunt cssmin
| |
| 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>
| |
| | |
| Ab sofort werden nicht mehr die Sourcedateien geladen, sondern die komprimierten, durch die Minifier erstellten Dateien.
| |
| 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">
| |
| npm install grunt-contrib-watch --save-dev
| |
| </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> | | </syntaxhighlight> |
|
| |
|
| Vergessen Sie nicht, das Plugin zu laden:
| | In dieser CSS-Datei werden folgende modernen CSS-Befehle verwendet: |
| <source lang="javascript">
| |
| grunt.loadNpmTasks('grunt-contrib-watch');
| |
| </source>
| |
|
| |
|
| Der Watch-Task überwacht drei verschiedene Ordner:
| | * Import-Befehl: <code>@import 'config.css';</code> |
| | * Konstanten: <code>--font-family-sans</code>, <code>--font-size-base</code> etc. (Es sind noch viele weitere konstante Werte in <code>body.css</code> enthalten, für die in <code>_config.css</code> Konstanten definiert werden sollten) |
| | * Verschachtelte Anweisungen: {{zB}} <code>h1</code> innerhalb von <code>#section_form</code> |
|
| |
|
| * 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.
| | Die verschachtelten Anweisungen strukturieren den CSS-Code deutlich besser. Es ist nicht mehr |
| * 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.
| | notwendig, einen Selektor wie <code>#section_form</code> mehrfach zu verwenden. |
| * 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.
| | Sehen Sie sich den Unterschied an. In der Datei <code>src/css/body.css</code> der Musterlösungen vom dritten Teil des Tutoriums hatte ich |
| Dies erfolgt entweder mit speziellen Browser-Plugins (http://livereload.com/extensions/) oder mit einem kleinen JavaScript-Hack:
| | Folgendes geschrieben: |
| Fügen Sie ans Ende der Datei „<code>main.js</code>“ folgenden Code ein:
| |
|
| |
|
| <source lang="javascript"> | | <syntaxhighlight lang="CSS"> |
| // Enable live reloading for the WebStorm web server.
| | #section_form |
| if (location.port === '63342') // WebStorm server port
| | { text-align: center; |
| { | | margin-left: auto; |
| var l_script = document.createElement('script'); | | margin-right: auto; |
| 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>
| |
| 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.
| |
| 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">
| |
| >> File "web/css/main.css" changed.
| |
| </source>
| |
| geschrieben und zum anderen ändert sich das Layout der HTML-Datei im Browser, da die aktualisierte CSS-Datei
| |
| 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.
| |
|
| |
| Das ist schon ziemlich „cool“, hat aber noch einen Schönheitsfehler: Das WebStorm-Terminal kann nicht anderweitig genutzt werden, solange
| |
| der Grunt-Watcher läuft. Um dieses Problem zu beheben, wird ein WebStorm-Startup-Task definiert, der den Watcher bei jedem
| |
| Programmstart von WebStorm automatisch in einem eigenständigen [[Task]] startet. Der Watcher läuft dann, solange WebStorm geöffnet ist.
| |
| Für seine Ausgaben steht im ein eigenes Ausgabefenster zur Verfügung. Was will man mehr?
| |
|
| |
| * <code>File</code> → <code>Settings</code> → <code>Tools</code> → <code>Startup Tasks</code> → <code></code>
| |
| * 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.
| |
| Wenn Sie das zugehörige Fenster öffnen sollte dort Folgendes stehen:
| |
|
| |
| <source lang="bash">
| |
| grunt watch
| |
| Running "watch" task
| |
| Waiting...
| |
| </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
| |
| (automatische Komprimierung bzw. Neuladen des HTML-Datei im Browser) automatisch ausgeführt. Der Watcher läuft solange, bis Sie WebStorm beenden.
| |
| 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">
| | #section_form > h1 |
| npm install grunt-contrib-jshint jshint-stylish --save-dev
| | { margin-bottom: 0.5ex; } |
| </source> | | </syntaxhighlight> |
|
| |
|
| Anschließend fügen Sie einen JSHit-Task in die Datei „<code>gruntfile.js</code>“ ein.
| | Die modernen CSS-Variante ist deutlich strukturierter und prägnanter. |
|
| |
|
| <source lang="javascript">
| | <syntaxhighlight lang="CSS"> |
| jshint:
| | #section_form |
| {
| | { text-align: center; |
| all: ['gruntfile.js', 'src/**/*.js'], | | margin-left: auto; |
| | margin-right: auto; |
|
| |
|
| options: | | h1 |
| { | | { margin-bottom: 0.5ex; } |
| esversion: 5,
| |
| eqeqeq: true,
| |
| eqnull: true,
| |
| browser: true,
| |
| reporter: require('jshint-stylish')
| |
| }
| |
| } | | } |
| </source> | | </syntaxhighlight> |
| | |
| | |
| Nun können alle vom Entwickler erstellten JavaScript-Dateien analysiert werden. Geben Sie dazu im
| |
| WebStorm-Terminal einfach folgenden Befehl ein:
| |
| | |
| <source lang="bash">
| |
| grunt jshint
| |
| </source>
| |
| | |
| Gut ist es, wenn JSHint mit der Meldung <code>v No problems</code> antwortet.
| |
| Ansonsten sollten Sie in Ihrem Code die von JSHint gemeldeten Probleme beheben.
| |
| | |
| 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">
| | Insbesondere bei großen CSS-Dateien erweist sich diese kompaktere Schreibweise als vorteilhaft. |
| Expected '===' and instead saw '=='.
| |
| </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
| |
| 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
| | Sie sollten nun [[HTML5-Tutorium: JavaScript: Hello World Vue 01|Teil 1 des Vue-Tutoriums]] bearbeiten. |
| JSHint anweisen für die Prüfung des nachfolgenden Codes spezielle Optionen zu benutzen, die dann {{iAllg}}
| | In diesem Teil des Tutoriums wird die oben erstelle Variante in das Vue-Framework transferiert. |
| eine etwas weniger strenge Überprüfung des Codes zur Folge haben (http://jshint.com/docs/).
| |
|
| |
|
| ==Quellen== | | ==Quellen== |
| <references/> | | <references/> |
| <ol> | | <ol> |
| <li value="3"> {{Quelle|Kowarschick, W.: Multimedia-Programmierung}}</li> | | <li value="5"> {{Quelle|Kowarschick, W.: Web-Programmierung}}</li> |
| </ol> | | </ol> |
| <noinclude>[[Kategorie: HTML5-Tutorium: JavaScript: Hello World]][[Kategorie: HTML5-Beispiel]][[Kategorie:Kapitel:Multimedia-Programmierung:Beispiele]]</noinclude> | | <noinclude>[[Kategorie: HTML5-Tutorium: JavaScript: Hello World]][[Kategorie: HTML5-Beispiel]][[Kategorie:Kapitel:Multimedia-Programmierung:Beispiele]]</noinclude> |
Dieser Artikel erfüllt die GlossarWiki-Qualitätsanforderungen nur teilweise:
Korrektheit: 3 (zu größeren Teilen überprüft)
|
Umfang: 4 (unwichtige Fakten fehlen)
|
Quellenangaben: 3 (wichtige Quellen vorhanden)
|
Quellenarten: 5 (ausgezeichnet)
|
Konformität: 3 (gut)
|
Vorlesung WebProg
Inhalt |
Teil 1 |
Teil 2 |
Teil 3 |
Teil 4 |
Teil 5 |
Teil 6 |
Vue 1 |
Vue 2 |
Vue 3 |
Vue 4 |
Vue 5 |
Vue 6
Musterlösung
index.html (HTML validate, CSS validate, Google PageSpeed)
Git-Repository
Anwendungsfälle (Use Cases)
Gegenüber dem dritten, vierten und fünften Teil des Tutoriums
ändern sich die die Anwendungsfälle nicht. Die Anwendung leistet also genau dasselbe wie zuvor.
In diesem Teil des Tutoriums geht es darum, den CSS-Code „DRY zu machen“.
Erstellen eines neuen Projekts
Erstellen Sie ein neues Projekt hello_world_06 als Fork von hello_world_05.
CSS-Erweiterungen
CSS bietet heute dieselbe Funktionalität wie Transpiler (SASS, Less etc.), die früher verwendet wurden, um fehlende Funktionalität in CSS zu integrieren. Ich werde in diesem Semester CSS an Stelle von SCSS einsetzen, so wie es von vite empfohlen wird:
Because Vite targets modern browsers only, it is recommended to use native CSS variables with PostCSS plugins that implement CSSWG drafts (e.g. postcss-nesting) and author plain, future-standards-compliant CSS. (https://vite.dev/guide/features)
Eine ganz wesentliche Erweiterung ist die Möglichkeit Konstanten zu definieren.
Auch die Möglichkeit, Werte zu berechnen, gibt es in der Zwischenzeit (SCSS: math, CSS: calc). Es ist jetzt auch möglich CSS-Elemente zu verschachteln.
Das heißt, die Bedeutung von SCSS, Less etc. schwindet.
CSS-Konstanten
Eine ganz wesentliche Erweiterung ist die Möglichkeit Konstanten zu definieren, da man damit CSS-Code DRY formulieren kann.
Wenn eine Konstante definiert wurde, kann man
im übrigen CSS-Code mittels var darauf zugreifen (und nicht etwa mittels const, :-( )
:root
{ --font-family-serif: "Times New Roman", Times, serif; }
p
{ font-family: var(--font-family-serif); }
label
{ font-family: var(--font-family-serif); }
Auch die Möglichkeit, Werte zu berechnen, gibt es in der Zwischenzeit (SCSS: math, CSS: calc).
Das heißt, die Bedeutung von SCSS, Less etc. schwindet. In diesem Semester verwende ich nicht mehr SCSS, sondern nur noch CSS.
Fügen Sie "config" als Abkürzung für "./src/css/_config.css" in die Datei vite.config.js ein.
...
resolve:
{ alias:
{ ...
'config.css': fileURLToPath(new URL('./src/css/_config.css', import.meta.url)),
...
}
}
...
In der Datei _config.css werden Konstanten definiert, die von allen anderen CSS-Dateien verwendet werden können und sollen.
Das heißt, das DRY-Prinzip „Konstanten gehören nicht in den Code, sondern in Konfigurationsdateien“ wird ab sofort beachtet.
Wenn man künftig am Layout einen Zeichensatz, eine Farbe, einen Hintergrund oder Ähnliches ändern will,
reicht es, die entsprechenden Konstanten anzupassen und schon erzeugt Vite automatisch aktualisiere
CSS-Dateien.
Durch den CSS-Import-Befehl ist es möglich, CSS-Dateien zu modularisieren.
Der Underscore _ am Beginn des Dateinamens deutet an, dass diese CSS-Datei nur von anderen CSS-Dateien
aber nicht von HTML- oder JavaScript-Dateien importiert werden sollte.
src/css/_config.css
:root
{ --background-color: #C5EFFC;
--font-family-sans: Verdana, Helvetica, sans-serif;
--font-family-serif: "Times New Roman", Times, serif;
--font-size-base: 3vw;
--font-size-factor: 1.25; /* cmp. https://type-scale.com/ */
--font-size-h5: calc(pow(var(--font-size-factor),1)*var(--font-size-base));
--font-size-h4: calc(pow(var(--font-size-factor),2)*var(--font-size-base));
--font-size-h3: calc(pow(var(--font-size-factor),3)*var(--font-size-base));
--font-size-h2: calc(pow(var(--font-size-factor),4)*var(--font-size-base));
--font-size-h1: calc(pow(var(--font-size-factor),5)*var(--font-size-base));
--font-size-p: calc(pow(var(--font-size-factor),0)*var(--font-size-base));
--font-size-p-large: calc(pow(var(--font-size-factor),2)*var(--font-size-base));
--font-size-small: calc(pow(var(--font-size-factor),-1)*var(--font-size-base));
}
In dieser CSS-Datei werden folgende modernen CSS-Konstrukte verwendet:
- Definition von Konstanten (die teilweise per Berechnung ermittelt werden)
- Mathematische Berechnungen:
calc
Konstanten starten in CSS mit zwei Minuszeichen. Sobald eine Konstante definiert wurde,
kann sie in allen weiteren CSS-Konstrukten verwendet werden. In CSS stehen einen Operatoren zur Verfügung wie
+, -, * und /, um Maße zu berechnen. Es gibt
weitere Operatoren zum Vergleichen von Zahlen und Maßen sowie zur Berechnung von Strings und booleschen Werten:
https://sass-lang.com/documentation/operators.[1]
Die Datei _config.css kann nun mit Hilfe des CSS-Befehls @import 'config.css'; (ohne Underscore und ohne .css, wegen des zuvor eingeführten Vite-Aliases)
in die anderen beiden CSS-Dateien eingefügt werden.
PostCSS
Der Inhalt der Datei _config.css wird defaultmäßig an den Browser ausgeliefert, obwohl sie nur CSS-Konstanten enthält.
Beim Einsatz vom SCSS werden Konstanten vom SCSS-Präprozessor auf dem Server während des Build-Prozesses durch ihre Werte ersetzt.
In CSS muss dies defaultmäßig der Browser übernehmen. Es gibt allerdings ein PostCSS-Plugin postcss-var-replace, das diese Ersetzungen ebenfalls während des Build-Prozesses vornimmt. Dieses kann man in die Vite-Konfiguration integrieren:
Laden sie das Pluging postcss-var-replace:
npm i -D postcss-var-replace
Anschließend aktivieren Sie es in vite.config.js
import { postcssVarReplace } from 'postcss-var-replace';
...
export default
{ ...
css:
{ postcss:
{ plugins:
[ postcssVarReplace(),
],
},
},
...
}
Der Import-Befehl hat ab sofort erst dann einen Effekt, wenn in den anderen Dateien auf diese Konstanten zugegriffen wird.
Aber er schadet auch nicht, wenn auf keine der dort definierten Konstanten zugegriffen wird. Der Import-Befehl selbst
taucht ebenso wenig in den generierten CSS-Dateien auf, wie die Konstantendefinitionen. Der PostCSS-Transpiler ersetzt Konstanten in CSS-Definitionen durch ihren jeweiligen Wert.
Sie können nun beispielsweise in der Datei head.css die Konstante --background-color
verwenden. In dem daraus durch den Build-Befehl npm run build erzeugten CSS-Style-Element steht weiterhin der Farbwert #C5EFFC;
src/css/head.css
@import 'config.css';
body
{ background-color: var(--background-color); }
.hidden
{ display: none; }
Die Datei body.css ist deutlich umfangreicher. Daher wird der zugehörige CSS-Code
ja auch erst dynamisch gemeinsam mit der Datei web/js/main.js geladen.
src/css/body.css
@import 'config.css';
html
{ height: 100%;
width: 100%;
display: table;
}
body
{ display: table-cell;
text-align: center;
vertical-align: middle;
font-size: var(--font-size-base);
font-family: var(--font-family-sans);
}
h1
{ padding: 0;
margin: 0;
font-size: var(--font-size-h1);
}
p, label
{ font-family: var(--font-family-serif);
font-size: var(--font-size-p);
}
label, input
{ width: 10em;
font-size: 100%;
display: inline-block;
box-sizing: border-box;
margin: 0.5ex;
}
label
{ text-align: right;
}
#section_form
{ text-align: center;
margin-left: auto;
margin-right: auto;
h1
{ margin-bottom: 0.5ex; }
}
#section_hello
{ p
{ font-size: var(--font-size-p-large) !important; }
}
In dieser CSS-Datei werden folgende modernen CSS-Befehle verwendet:
- Import-Befehl:
@import 'config.css';
- Konstanten:
--font-family-sans, --font-size-base etc. (Es sind noch viele weitere konstante Werte in body.css enthalten, für die in _config.css Konstanten definiert werden sollten)
- Verschachtelte Anweisungen: z. B.
h1 innerhalb von #section_form
Die verschachtelten Anweisungen strukturieren den CSS-Code deutlich besser. Es ist nicht mehr
notwendig, einen Selektor wie #section_form mehrfach zu verwenden.
Sehen Sie sich den Unterschied an. In der Datei src/css/body.css der Musterlösungen vom dritten Teil des Tutoriums hatte ich
Folgendes geschrieben:
#section_form
{ text-align: center;
margin-left: auto;
margin-right: auto;
}
#section_form > h1
{ margin-bottom: 0.5ex; }
Die modernen CSS-Variante ist deutlich strukturierter und prägnanter.
#section_form
{ text-align: center;
margin-left: auto;
margin-right: auto;
h1
{ margin-bottom: 0.5ex; }
}
Insbesondere bei großen CSS-Dateien erweist sich diese kompaktere Schreibweise als vorteilhaft.
Fortsetzung des Tutoriums
Sie sollten nun Teil 1 des Vue-Tutoriums bearbeiten.
In diesem Teil des Tutoriums wird die oben erstelle Variante in das Vue-Framework transferiert.
Quellen
- Kowarschick (WebProg): Wolfgang Kowarschick; Vorlesung „Web-Programmierung“; Hochschule: Hochschule Augsburg; Adresse: Augsburg; Web-Link; 2024; Quellengüte: 3 (Vorlesung)