Aufwärmen · Aufgabe 1 von 7
Zum Aufwärmen aus Lektion B4.4 zum Scope. Was gibt dieser Code aus?
{
const secret = 42;
}
console.log(typeof secret);// I3.1 · ca. 34 Min. · Aufbau
Nach dieser Lektion teilen Sie ein Programm auf mehrere Dateien auf: Jede Datei exportiert, was andere nutzen dürfen, importiert, was sie braucht, und hält alles andere privat.
Lektion 1 von 5 in I3 Module, Node.js und npm
Danach können Sie
Aufwärmen · Aufgabe 1 von 7
{
const secret = 42;
}
console.log(typeof secret);Vorhersagen · Aufgabe 2 von 7
// counter.js
console.log("counter.js runs");
export let count = 0;
// logger.js
import {count} from "./counter.js";
export const start = count;
// main.js
import {count} from "./counter.js";
import {start} from "./logger.js";
console.log("main runs");Üben · Aufgabe 3 von 7
____ const VAT = 0.19;Üben · Aufgabe 4 von 7
Üben · Aufgabe 5 von 7
// math.js
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
// main.js
import {add, multiply} from "./math.js";
console.log(multiply(add(1, 2), 4));Denksport · Aufgabe 6 von 7
// setup.js
console.log("setup");
// main.js
console.log("main");
import "./setup.js";Anwenden · Aufgabe 7 von 7
Prüfen Sie Ihr Ergebnis anhand dieser Liste
Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.
Ausgearbeitetes Beispiel
prices.js exportiert withVat und currency und hält VAT privat. counter.js exportiert count und increment und gibt aus, wenn es läuft. logger.js importiert counter.js ebenfalls. main.js importiert aus allen dreien. Die Ausgabe zeigt, dass counter.js einmal lief, dass main.js VAT nicht sehen kann, dass count eine Live-Bindung ist, die beide Aufrufe von increment() geändert haben, und dass main.js ihr nichts zuweisen kann.
main.js
import {withVat, currency} from "./prices.js";
import {count, increment} from "./counter.js";
import {log} from "./logger.js"; // logger.js imports counter.js too
console.log(withVat(10), currency);
console.log(typeof VAT); // VAT belongs to prices.js
increment();
log("hello");
console.log("count:", count); // a live binding: 2
try {
count = 10;
} catch (error) {
console.log(error.name + ":", error.message);
}
prices.js
const VAT = 0.19; // not exported: private to this file
export function withVat(net) {
return Math.round(net * (1 + VAT) * 100) / 100;
}
export const currency = "EUR";
counter.js
console.log("counter.js runs");
export let count = 0;
export function increment() {
count += 1;
}
logger.js
import {increment} from "./counter.js";
export function log(message) {
increment();
console.log("log:", message);
}
Ausführen mit
node main.jsAusgabe
counter.js runs
11.9 EUR
undefined
log: hello
count: 2
TypeError: Assignment to constant variable.Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.
Übung 1 von 2
main.js ist ein Modul, das andere Dateien importieren werden. Es soll genau zwei Funktionen exportieren: slugify(title), das "Hello World!" in "hello-world" verwandelt, und isSlug(text). Die Hilfsfunktion clean(text) wird nur innerhalb der Datei benutzt und muss privat bleiben. Der Startcode exportiert auch clean. Entfernen Sie diesen Export, sodass die öffentliche API des Moduls nur aus den beiden Funktionen besteht.
Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.
Führen Sie die Tests aus: Das Modul exportiert drei Namen. Welcher ist nur ein Helfer?
Eine Funktion ohne export ist innerhalb ihrer eigenen Datei trotzdem nutzbar.
Löschen Sie das Wort export vor function clean.
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
function clean(text) {
return text.toLowerCase().replace(/[^a-z0-9 ]/g, "").trim();
}
export function slugify(title) {
return clean(title).split(/ +/).join("-");
}
export function isSlug(text) {
return /^[a-z0-9]+(-[a-z0-9]+)*$/.test(text);
}
Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.
main.js
export function clean(text) {
return text.toLowerCase().replace(/[^a-z0-9 ]/g, "").trim();
}
export function slugify(title) {
return clean(title).split(/ +/).join("-");
}
export function isSlug(text) {
return /^[a-z0-9]+(-[a-z0-9]+)*$/.test(text);
}
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import * as slugs from './main.js';
test('Das Modul exportiert genau slugify und isSlug', () => {
const names = Object.keys(slugs).sort();
assert.deepEqual(names, ['isSlug', 'slugify'], `main.js exportiert ${JSON.stringify(names)}`);
});
test('slugify macht aus einem Titel einen Slug', () => {
const got = slugs.slugify('Hello World!');
assert.equal(got, 'hello-world', `slugify gab ${got}`);
});
test('isSlug akzeptiert einen Slug und lehnt einen Titel ab', () => {
assert.equal(slugs.isSlug('hello-world'), true, 'hello-world ist ein Slug');
assert.equal(slugs.isSlug('Hello World'), false, 'Hello World ist kein Slug');
});
package.json
{
"type": "module"
}
package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.
Programm ausführen:
node main.jsPrüfungen ausführen (learnrun.js muss im selben Ordner liegen):
node --testlearnrun.js herunterladenÜbung 2 von 2
main.js ist ein kleines Speichermodul. Es soll addItem(name) und count exportieren, die Anzahl der bisherigen Artikel, sodass ein Importeur count nach jedem addItem sich ändern sieht. Der Startcode exportiert count als items.length, einmal berechnet, als das Modul lief, es bleibt also 0. Machen Sie count zu einem let, das addItem aktualisiert.
Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.
Führen Sie die Tests aus: count bleibt 0. Wann wird items.length im Startcode gelesen?
Ein importiertes let ist eine Live-Bindung: Weist main.js einen neuen Wert zu, sehen ihn die Importeure.
export let count = 0; und in addItem: count = items.length;
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
const items = [];
export let count = 0;
export function addItem(name) {
items.push(name);
count = items.length;
}
Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.
main.js
const items = [];
export function addItem(name) {
items.push(name);
}
export const count = items.length;
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {addItem, count} from './main.js';
import * as store from './main.js';
test('count beginnt bei 0', () => {
assert.equal(store.count, 0, `count ist ${store.count}, bevor es einen Artikel gibt`);
});
test('Das importierte count folgt addItem', () => {
addItem('tea');
addItem('cake');
assert.equal(count, 2, `nach zwei Artikeln ist das importierte count ${count}`);
});
package.json
{
"type": "module"
}
package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.
Programm ausführen:
node main.jsPrüfungen ausführen (learnrun.js muss im selben Ordner liegen):
node --testlearnrun.js herunterladenimport {sum} from "./math.js";
console.log(sum(1, 2));
Was Node.js ausgibt
SyntaxError: The requested module './math.js' does not provide an export named 'sum'Warum, und die Lösung
Die Namen in den geschweiften Klammern müssen genau die exportierten Namen sein. math.js exportiert add, nicht sum, das Modul lässt sich also nicht verknüpfen, und nichts läuft. Importieren Sie add, oder benennen Sie beim Import um: import {add as sum} from "./math.js". Der Fehler ist ein SyntaxError, obwohl die Syntax stimmt: Er tritt beim Verknüpfen der Module auf, bevor irgendein Code läuft.
import {count} from "./counter.js";
count = count + 1;
console.log(count);
Was Node.js ausgibt
TypeError: Assignment to constant variable.Warum, und die Lösung
Ein Import ist in der importierenden Datei nur lesbar, auch wenn das exportierende Modul ihn mit let deklariert hat. Nur counter.js kann count ändern. Exportieren Sie eine Funktion, die das tut, etwa export function increment() { count += 1; }, und rufen Sie diese auf.
import {add} from "./math";
console.log(add(1, 2));
Was Node.js ausgibt
Error [ERR_MODULE_NOT_FOUND]: Cannot find moduleWarum, und die Lösung
Node.js probiert bei einem ES-Modul-Pfad keine Endungen aus: "./math" sucht eine Datei, die genau math heißt und nicht existiert. Ein Browser würde die URL ./math anfordern und genauso scheitern. Schreiben Sie den vollen Dateinamen: "./math.js".
JavaScript im Browser: die eigene Engine Ihres Browsers in einem abgeschotteten Worker. Syntaxfehler findet acorn 8.18.0, MIT. Lizenz und Quellcode
5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.
Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.