# Einstieg in JavaScript-Dialekte und TypeScript-Konfiguration

## ✨ Ziel dieses Dokuments

Diese Anleitung richtet sich an Anfänger, die lernen wollen, wann sie welchen JavaScript-Dialekt (CommonJS vs. ESM) verwenden sollten, wie sie TypeScript korrekt konfigurieren und worauf sie bei modernen Projekten achten müssen.

## Inhalt

- [Einstieg in JavaScript-Dialekte und TypeScript-Konfiguration](#einstieg-in-javascript-dialekte-und-typescript-konfiguration)
  - [✨ Ziel dieses Dokuments](#-ziel-dieses-dokuments)
  - [Inhalt](#inhalt)
  - [🔢 Begriffe erklärt](#-begriffe-erklärt)
    - [JavaScript-Dialekte (Modulsysteme)](#javascript-dialekte-modulsysteme)
    - [Was ist TypeScript?](#was-ist-typescript)
  - [🔍 Wann verwende ich was?](#-wann-verwende-ich-was)
  - [🔧 TypeScript richtig konfigurieren](#-typescript-richtig-konfigurieren)
    - [📦 Was ist ESM?](#-was-ist-esm)
    - [✅ Wann kann/sollte/muss man **ESM** verwenden?](#-wann-kannsolltemuss-man-esm-verwenden)
      - [🟢 **Du kannst ESM verwenden**, wenn](#-du-kannst-esm-verwenden-wenn)
      - [🟡 **Du solltest ESM verwenden**, wenn](#-du-solltest-esm-verwenden-wenn)
      - [🔴 **Du musst ESM verwenden**, wenn](#-du-musst-esm-verwenden-wenn)
    - [⚙️ TypeScript-Konfiguration für ESM](#️-typescript-konfiguration-für-esm)
    - [📌 Merkmale von ESM](#-merkmale-von-esm)
    - [⚠️ Besonderheiten und Stolperfallen](#️-besonderheiten-und-stolperfallen)
    - [✅ Fazit ESM](#-fazit-esm)
  - [🌐 CommonJS-Konfiguration CJS (Alternative)](#-commonjs-konfiguration-cjs-alternative)
    - [📦 Was ist CommonJS?](#-was-ist-commonjs)
    - [✅ Wann kann/sollte/muss man **CommonJS** verwenden?](#-wann-kannsolltemuss-man-commonjs-verwenden)
      - [🟢 **Du kannst CJS verwenden**, wenn](#-du-kannst-cjs-verwenden-wenn)
      - [🟡 **Du solltest CJS verwenden**, wenn](#-du-solltest-cjs-verwenden-wenn)
      - [🔴 **Du musst CJS verwenden**, wenn](#-du-musst-cjs-verwenden-wenn)
    - [⚙️ TypeScript-Konfiguration für CJS](#️-typescript-konfiguration-für-cjs)
    - [📌 Merkmale von CommonJS](#-merkmale-von-commonjs)
    - [✅ Fazit CommonJS](#-fazit-commonjs)
  - [📄 Fazit: Empfehlungen](#-fazit-empfehlungen)
  - [📁 Dateiendungen in Node.js](#-dateiendungen-in-nodejs)
  - [⚠️ Typische Fehler vermeiden](#️-typische-fehler-vermeiden)
  - [🚀 CLI-Build-Tipps (tsc)](#-cli-build-tipps-tsc)
  - [📍 Weiterführende Themen](#-weiterführende-themen)

---

## 🔢 Begriffe erklärt

### JavaScript-Dialekte (Modulsysteme)

| Name               | Kürzel | Typ         | Verwendung heute        |
| ------------------ | ------ | ----------- | ----------------------- |
| CommonJS           | CJS    | `require()` | Ältere Node.js-Projekte |
| ECMAScript Modules | ESM    | `import`    | Browser, moderne Tools  |

- **CommonJS:** Nutzt `require()` und `module.exports`. Standard bis Node 12.  
- **ESM:** Nutzt `import`/`export`. Standard im Browser und in Node ab Version 14+.  

### Was ist TypeScript?

TypeScript ist eine statisch typisierte Obermenge von JavaScript, die zu normalem JS kompiliert wird.  

---

## 🔍 Wann verwende ich was?

| Ziel                       | Modulformat  | Empfehlung     | Grund                                      |  
| -------------------------- | ------------ | -------------- | ------------------------------------------ |  
| 📅 Moderne Webanwendung    | ESM          | Ja             | Browser erwartet ESM                       |  
| 📄 Node.js CLI-Tool        | ESM oder CJS | Beides möglich | ESM zukunftssicher, CJS maximal kompatibel |  
| 🔐 Legacy-Node-Integration | CJS          | Ja             | Viele NPM-Pakete sind CJS-only             |  
| 🔌 Electron Renderer       | ESM          | Ja (Pflicht)   | Chromium-only, kein CJS                    |  
| 🔁 Vite/Webpack-Projekt    | ESM          | Ja             | Toolchain basiert auf ESM                  |  

---

## 🔧 TypeScript richtig konfigurieren

Eine vollständige Zusammenfassung zu **ESM (ECMAScript Modules)** – wann du es **verwenden kannst**, **solltest** oder **musst**, sowie alle wesentlichen technischen Eigenschaften. Stil und Umfang entsprechen exakt der vorherigen CommonJS-Zusammenfassung.

---

### 📦 Was ist ESM?

**ESM (ECMAScript Modules)** ist das moderne Modulsystem von JavaScript:

- verwendet `import`/`export`-Syntax
- wird nativ von allen modernen Browsern und Node.js (ab v14+) unterstützt
- ist Standard in allen modernen JS-Toolchains (Vite, Webpack, esbuild, etc.)

```js
// ESM-Stil
import fs from 'node:fs/promises';
export function read(path) {
  return fs.readFile(path, 'utf-8');
}
```

---

### ✅ Wann kann/sollte/muss man **ESM** verwenden?

#### 🟢 **Du kannst ESM verwenden**, wenn

- du mit **modernen Node.js-Versionen (v16+)** arbeitest
- du ein **Frontend-Tool** oder ein **Browser-kompatibles Projekt** baust
- du Tree-Shaking oder Dynamic `import()` nutzen willst
- du Typkonsistenz mit dem Browser willst (gleiche Syntax wie dort)

#### 🟡 **Du solltest ESM verwenden**, wenn

| Situation                                                           | Grund                        |
| ------------------------------------------------------------------- | ---------------------------- |
| 🌐 Du entwickelst Webanwendungen mit Vite, Nuxt, Webpack o. ä.      | Diese Tools basieren auf ESM |
| 💡 Du möchtest moderne Syntax und Tooling nutzen                    | ESM ist Standard             |
| 🔄 Du willst `import()` dynamisch verwenden                         | Nur in ESM verfügbar         |
| 📚 Du schreibst eine wiederverwendbare Bibliothek für neue Projekte | Zukunftssicherheit           |
| 🧩 Du verwendest Deno, Bun oder moderne Plattformen                 | ESM only                     |

#### 🔴 **Du musst ESM verwenden**, wenn

- du im **Browser** arbeitest (ohne Bundler) → dort ist `import` Pflicht  
- du in **Electron-Renderer-Prozessen** arbeitest  
- du ein Projekt hast mit `"type": "module"` und `.js`-Dateien → dann interpretiert Node sie nur als ESM  
- du ESM-only-Dependencies nutzt (z. B. `chalk@5`, `node-fetch@3`)  

---

### ⚙️ TypeScript-Konfiguration für ESM

```jsonc
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}
```

Und in der `package.json`:

```json
{
  "type": "module"
}
```

**Wichtig:** Ohne `"type": "module"` behandelt Node deine `.js`-Dateien **nicht als ESM**, sondern als CommonJS.

---

### 📌 Merkmale von ESM

| Merkmal                   | ESM                                          |
| ------------------------- | -------------------------------------------- |
| Import-Syntax             | `import`, `export`                           |
| Export-Syntax             | `export default`, `export {...}`             |
| Dateiendung `.js`         | **.js** nur mit `"type": "module"`           |
| `.mjs`                    | explizit ESM                                 |
| `__dirname`, `__filename` | ❌ nicht vorhanden, nur via `import.meta.url` |
| Dynamische Imports        | ✅ `await import('...')`                      |
| Tree Shaking              | ✅ möglich                                    |
| Browser-kompatibel        | ✅ nativ                                      |
| CommonJS-Interop          | ❗ mit Einschränkungen (`createRequire`)      |

---

### ⚠️ Besonderheiten und Stolperfallen

| Problem                                       | Lösung                                      |
| --------------------------------------------- | ------------------------------------------- |
| ❌ `__dirname`/`__filename` fehlen             | nutze `import.meta.url` + `fileURLToPath()` |
| ❌ `require()` nicht verfügbar                 | verwende `import`, oder `createRequire()`   |
| ❌ `.js` muss beim Import angegeben werden     | z. B. `import './utils.js'`                 |
| ❌ viele alte Pakete sind nicht ESM-kompatibel | ggf. CommonJS verwenden                     |

---

### ✅ Fazit ESM

> **ESM ist der offizielle Standard für moderne JavaScript-Entwicklung** – sowohl im Browser als auch in modernen Node.js-Umgebungen.

Du solltest ESM verwenden, wenn du:

- neue Projekte startest,
- moderne Toolchains nutzt,
- oder langfristige Kompatibilität willst.

In Zweifelsfällen gilt: **Wenn du mit aktuellen Tools und Node-Versionen arbeitest, nimm ESM.**
Nur bei Problemen mit alten Paketen oder Tooling solltest du temporär auf CommonJS zurückfallen.

---

## 🌐 CommonJS-Konfiguration CJS (Alternative)

### 📦 Was ist CommonJS?

**CommonJS (CJS)** ist das ursprüngliche Modulsystem von Node.js:

- verwendet `require()` zum Importieren
- verwendet `module.exports` oder `exports` zum Exportieren
- keine native Unterstützung für `import`/`export`
- funktioniert nur in Node.js (nicht im Browser ohne Bundler)

```js
// CommonJS-Stil
const fs = require('fs');
module.exports = { read: fs.readFileSync };
```

---

### ✅ Wann kann/sollte/muss man **CommonJS** verwenden?

#### 🟢 **Du kannst CJS verwenden**, wenn

- du ein CLI-Tool oder Node.js-Skript erstellst  
- du maximale **Kompatibilität** ohne ESM-Komplikationen willst  
- du keine modernen ESM-Features brauchst  
- du auf Build-Tools verzichtest und direkt `.js`-Dateien startest  

#### 🟡 **Du solltest CJS verwenden**, wenn

| Situation                                                           | Grund                                                  |
| ------------------------------------------------------------------- | ------------------------------------------------------ |
| 🔄 Du arbeitest mit älteren Node.js-Versionen (z. B. v12 oder v10)  | ESM ist dort nicht stabil                              |
| 📦 Du nutzt NPM-Pakete, die **kein ESM unterstützen**               | `require()` wird erwartet                              |
| 🧪 Du verwendest alte Tools, Tests oder Konfigurationen             | z. B. alte `mocha`, `gulpfile.js`, `webpack.config.js` |
| 🧱 Du brauchst direkten Zugriff auf `__dirname`, `__filename`       | Diese fehlen in ESM                                    |
| 📜 Du möchtest `.js`-Dateien ohne `.mjs` oder `type: module` nutzen | CommonJS macht keine Vorgaben für Dateiendungen        |

#### 🔴 **Du musst CJS verwenden**, wenn

- das Node.js-Modul, das du importieren willst, **nur `module.exports` exportiert** (kein ESM-Support)  
- dein Projekt oder Tool **nicht mit ESM kompatibel ist** (ältere Tooling oder NPM-Module)  
- du `require()` oder dynamisches Laden (`require(dynamicPath)`) verwendest, was in ESM nicht geht  

---

### ⚙️ TypeScript-Konfiguration für CJS

```jsonc
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true
  }
}
```

Und in der `package.json`:

```json
{
  "type": "commonjs"
}
```

**Hinweis:** Das `"type"`-Feld ist für Node wichtig, nicht für TypeScript.

---

### 📌 Merkmale von CommonJS

| Merkmal                   | CommonJS                   |
| ------------------------- | -------------------------- |
| Import-Syntax             | `require()`                |
| Export-Syntax             | `module.exports = …`       |
| Dateiendung               | `.js` (keine `.mjs` nötig) |
| Direkt ausführbar         | ✅ Ohne zusätzliche Flags   |
| `__dirname`, `__filename` | ✅ verfügbar                |
| Browserkompatibilität     | ❌ Nur mit Bundler möglich  |
| Dynamische Importe        | ✅ `require(dynamicPath)`   |
| Tree Shaking              | ❌ nicht möglich            |

---

### ✅ Fazit CommonJS

> **CommonJS ist stabil, weit verbreitet und maximal kompatibel.**
> Wenn du **einfach nur ein Node-Tool oder CLI-Skript baust** und keine besonderen Build-Prozesse oder Browser-Kompatibilität brauchst: **Nutze CommonJS.**

Für moderne ESM-Projekte im Web oder wenn du zukunftssicher entwickeln willst, solltest du auf ESM setzen – aber CJS bleibt in vielen Fällen die einfachste und robusteste Wahl.  

---

## 📄 Fazit: Empfehlungen

- **Neue Projekte:** Nutze ESM mit `"type": "module"`
- **Bestehende Tools nutzen `require()`?** Dann CJS
- **Browser + Node gemeinsam nutzen?** ESM-only + klare Trennung von `shared/`, `client/`, `server/`
- **Tooling wie Vite, Nuxt, Webpack?** Immer ESM

---

## 📁 Dateiendungen in Node.js

| Dateiendung | Verhalten           |
| ----------- | ------------------- |
| `.js`       | Hängt von `type` ab |
| `.mjs`      | Immer ESM           |
| `.cjs`      | Immer CommonJS      |

---

## ⚠️ Typische Fehler vermeiden

- **`SyntaxError: Cannot use import statement outside a module`**
  → `type` fehlt in `package.json`

- **`Cannot find module` bei relativen Imports**
  → `.js` fehlt am Ende beim ESM-Import

- **`__dirname` ist not defined**
  → Du nutzt ESM, verwende `import.meta.url`

---

## 🚀 CLI-Build-Tipps (tsc)

```bash
npx tsc         # Kompiliert Projekt laut tsconfig.json
chmod +x dist/index.js   # Macht CLI-Datei ausführbar
```

Header für CLI-Datei:

```ts
#!/usr/bin/env node
```

---

## 📍 Weiterführende Themen

- Dual-Exports für NPM (ESM + CJS gleichzeitig)  
- "exports"-Feld in `package.json`  
- Tools wie `tsup`, `vite`, `esbuild` als Alternativen zu `tsc`  
- Einstieg in CLI-Tools: `commander`, `yargs`, `chalk`, `ora`  
