Zum Hauptinhalt springen
Edge Computing und JavaScript-Module: Warum ESM die Zukunft gehört
#Edge Computing #ESM #CommonJS #JavaScript #Cloudflare Workers

Edge Computing und JavaScript-Module: Warum ESM die Zukunft gehört


Wie Edge-Plattformen das Ende von CommonJS einläuten – und ESM zum Standard machen

12 Minuten Lesezeit

Edge Computing verändert, wie wir JavaScript deployen. Und mit diesem Wandel verschiebt sich auch, welche Modul-Systeme überhaupt noch funktionieren. CommonJS, jahrelang der Standard in Node.js, stößt an seine Grenzen. ESM übernimmt – nicht aus Prinzip, sondern aus Notwendigkeit.

CommonJS und ESM: Die Kurzfassung

Bevor es um Edge geht, die Grundlagen:

AspektCommonJSESM
Syntaxrequire() / module.exportsimport / export
LadenSynchron (blockierend)Asynchron (nicht-blockierend)
Tree ShakingNeinJa
Browser-SupportNein (Bundler nötig)Nativ
Node.jsDefault bis heuteAb Node 12+, Default ab Node 20+

CommonJS wurde für Server entwickelt – synchrones Laden ist dort kein Problem. ESM wurde für das Web entwickelt – asynchron, optimierbar, zukunftssicher.

ESM in Node.js aktivieren

Für ESM in Node.js gibt es zwei Wege:

Option 1: package.json anpassen:

{
  "type": "module"
}

Option 2: Dateiendung .mjs verwenden.

Bei Imports immer die Dateiendung angeben:

import { foo } from './utils.js';  // nicht './utils'

Warum Edge-Plattformen CommonJS ablösen

Edge Computing bedeutet: Code läuft nicht in einem zentralen Rechenzentrum, sondern verteilt an hunderten Standorten weltweit – nah am Nutzer. Die Anforderungen sind radikal anders:

  • Kalte Starts in Millisekunden – keine Zeit für synchrones Laden
  • Winzige Bundles – jedes Kilobyte zählt
  • Isolation – jede Anfrage läuft in einer eigenen Sandbox

CommonJS passt nicht in diese Welt. Es wurde für langlebige Server-Prozesse gebaut, nicht für kurzlebige Edge-Funktionen.

Die großen Edge-Plattformen

PlattformESM-SupportCommonJSBesonderheiten
Cloudflare WorkersVollständigEingeschränktV8 Isolates, unter 50ms Cold Start
Vercel Edge FunctionsVollständigÜber BundlerNext.js-Integration
Deno DeployVollständigNeinWeb-Standards first
Netlify Edge FunctionsVollständigEingeschränktDeno-basiert

Deno Deploy ist konsequent: Kein CommonJS, nur ESM und Web-APIs. Cloudflare und Vercel bieten Kompatibilitätsschichten, aber die Richtung ist klar.

ESM auf dem Edge: Die technischen Vorteile

Tree Shaking funktioniert

ESM ermöglicht statische Analyse zur Build-Zeit. Der Bundler sieht exakt, welche Exports verwendet werden – und entfernt den Rest.

// utils.js
export function foo() { /* ... */ }
export function bar() { /* ... */ }  // wird nie importiert

// app.js
import { foo } from './utils.js';

Bei ESM landet nur foo im Bundle. Bei CommonJS landet alles – weil require() dynamisch ist und der Bundler nicht wissen kann, was zur Laufzeit gebraucht wird.

Asynchrones Laden

ESM lädt Module asynchron und parallel. Das ist entscheidend für Edge-Funktionen, die in Millisekunden starten müssen.

// ESM: parallel laden
const [moduleA, moduleB] = await Promise.all([
  import('./a.js'),
  import('./b.js')
]);

CommonJS blockiert bei jedem require() – fatal für Cold Starts.

Top-Level Await

ESM erlaubt await auf oberster Ebene:

// ESM
const config = await fetch('/config.json').then(r => r.json());
export { config };

In CommonJS braucht es dafür Workarounds oder IIFEs.

Migration: Von CommonJS zu ESM

Schritt 1: package.json anpassen

{
  "type": "module",
  "exports": {
    ".": "./src/index.js"
  }
}

Schritt 2: Imports umschreiben

// Vorher (CommonJS)
const express = require('express');
const { readFile } = require('fs/promises');
const config = require('./config.json');

// Nachher (ESM)
import express from 'express';
import { readFile } from 'fs/promises';
// JSON-Import (Node.js 20+)
import config from './config.json' assert { type: 'json' };

Schritt 3: Exports umschreiben

// Vorher
module.exports = { foo, bar };
module.exports.baz = baz;

// Nachher
export { foo, bar };
export { baz };
// oder
export default { foo, bar, baz };

Schritt 4: __dirname und __filename ersetzen

// Vorher (CommonJS)
const path = require('path');
const configPath = path.join(__dirname, 'config.json');

// Nachher (ESM)
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const configPath = join(__dirname, 'config.json');

Schritt 5: Dynamische Imports für Conditional Loading

// Vorher (CommonJS)
let adapter;
if (process.env.DB === 'postgres') {
  adapter = require('./adapters/postgres');
} else {
  adapter = require('./adapters/sqlite');
}

// Nachher (ESM)
const adapter = await import(
  process.env.DB === 'postgres' 
    ? './adapters/postgres.js' 
    : './adapters/sqlite.js'
);

Edge-Apps bauen: Praxisbeispiele

Cloudflare Workers mit ESM

// worker.js
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    
    if (url.pathname === '/api/hello') {
      return Response.json({ message: 'Hello from the Edge!' });
    }
    
    return new Response('Not Found', { status: 404 });
  }
};

Kein require, kein module.exports – pure ESM mit Web-Standard-APIs.

Vercel Edge Functions

// api/edge.js
export const config = { runtime: 'edge' };

export default async function handler(request) {
  const { searchParams } = new URL(request.url);
  const name = searchParams.get('name') || 'World';
  
  return new Response(`Hello, ${name}!`, {
    headers: { 'content-type': 'text/plain' }
  });
}

Deno Deploy

// main.ts
Deno.serve((request: Request) => {
  const url = new URL(request.url);
  
  if (url.pathname === '/') {
    return new Response('Welcome to Deno Deploy!');
  }
  
  return new Response('Not Found', { status: 404 });
});

Deno braucht keine Konfiguration – ESM und TypeScript sind native.

CommonJS auf Edge: Die Einschränkungen

Manche Edge-Plattformen erlauben CommonJS über Bundler-Transformationen. Das funktioniert, hat aber Nachteile:

  • Größere Bundles – kein echtes Tree Shaking
  • Langsamere Builds – zusätzliche Transformation nötig
  • Potenzielle Inkompatibilitäten – nicht alle CJS-Patterns lassen sich transformieren

Für Legacy-Code ist das ein Übergangspfad. Für neue Projekte gibt es keinen Grund, CommonJS zu wählen.

DSGVO und Edge: Ein Vorteil

Edge Computing kann DSGVO-Konformität vereinfachen: Daten werden in der Region verarbeitet, in der sie entstehen. Cloudflare bietet EU-only-Verarbeitung, Vercel hat europäische Edge-Standorte.

Das hat nichts mit ESM vs. CommonJS zu tun – aber es ist ein weiterer Grund, Edge-Deployment ernst zu nehmen.

Performance-Vergleich

MetrikCommonJS (Node.js)ESM (Edge)
Cold Start100-500ms5-50ms
Bundle Size (typisch)500KB-2MB50-200KB
Time to First Byte50-200ms5-30ms
Globale LatenzAbhängig vom Server-Standortunter 50ms weltweit

Die Zahlen variieren je nach Anwendung, aber die Größenordnung ist konsistent: Edge mit ESM ist schneller.

Wann CommonJS noch Sinn macht

  • Legacy-Projekte mit großer Codebasis – Migration braucht Zeit
  • Interne Tools ohne Performance-Anforderungen
  • Abhängigkeiten die nur als CJS verfügbar sind (werden weniger)

Für neue Projekte, öffentliche APIs und alles mit Nutzer-facing Performance: ESM.


Die Entwicklung ist eindeutig: Edge-Plattformen setzen auf ESM, Web-Standards und asynchrone Patterns. CommonJS bleibt für Legacy-Code nutzbar, aber die Zukunft von JavaScript auf dem Server – und erst recht auf dem Edge – ist ESM.

Wer heute noch ein neues Projekt mit CommonJS startet, baut technische Schulden auf. Die Migration ist nicht schwer, aber sie wird nicht einfacher, je länger man wartet.