Start · Sprachen · JavaScript · Referenz · import()

import()

Operator

Lädt ein ECMAScript-Modul <strong>asynchron und dynamisch</strong> zur Laufzeit und gibt ein <code>Promise</code> zurück, das zum Modul-Namespace-Objekt auflöst.

seit JavaScript ES2020 Kategorie: syntax

Signatur

import(modulSpecifier)

Beschreibung

import() – auch als dynamischer Import bezeichnet – ist ein funktionsähnlicher Ausdruck, der es erlaubt, ECMAScript-Module zur Laufzeit und bedarfsgesteuert zu laden. Anders als das statische import-Statement muss import() nicht am Anfang einer Datei stehen, kann innerhalb von Bedingungen, Schleifen oder Event-Handlern aufgerufen werden und funktioniert auch in Nicht-Modul-Kontexten (z. B. klassischen <script>-Tags).

Der Aufruf gibt ein Promise<ModuleNamespace> zurück. Löst das Promise auf, erhält man ein Modul-Namespace-Objekt: ein Objekt, dessen Eigenschaften den benannten Exporten des Moduls entsprechen. Der Standard-Export (default) ist als .default-Eigenschaft verfügbar. Schlägt das Laden fehl (Netzwerkfehler, Syntaxfehler im Modul, falscher Pfad), wird das Promise abgelehnt.

Typische Einsatzgebiete sind Code-Splitting (nur den Code laden, der gerade benötigt wird), Lazy Loading von UI-Komponenten oder Bibliotheken, das Laden von Modulen abhängig von Nutzerinteraktionen sowie das Einbinden optionaler Polyfills. In Build-Tools wie Webpack oder Vite dient import() als Signal für automatisches Chunk-Splitting.

Obwohl die Syntax wie ein Funktionsaufruf aussieht, ist import() ein eigener Sprachoperator – er kann nicht über Function.prototype.call oder ähnliche Mechanismen umgeleitet werden, und der Modulbezeichner muss ein String-Literal oder ein Ausdruck sein, der zur Laufzeit zu einem String ausgewertet wird.

Parameter

Name Typ Default Beschreibung
$modulSpecifier Pflicht string Der Pfad oder die URL des zu ladenden Moduls. Kann ein relativer Pfad ('./utils.js'), ein absoluter URL-String, ein Bare-Specifier (z. B. 'lodash' in Node.js/Build-Tools) oder ein dynamisch zusammengesetzter String sein.
$options object Optionales Konfigurationsobjekt. Aktuell wird { assert: { type: 'json' } } (bzw. { with: { type: 'json' } } im neueren Standard) für Import-Assertions/Attributes unterstützt, um z. B. JSON-Module explizit zu kennzeichnen. Browser-Unterstützung ist noch unterschiedlich.

Rückgabewert

Typ
Promise<ModuleNamespace>
Beschreibung
Ein Promise, das bei Erfolg zu einem Modul-Namespace-Objekt auflöst. Dessen Eigenschaften entsprechen den benannten Exporten des Moduls; der Default-Export ist über .default erreichbar. Bei Ladefehlern oder Syntaxfehlern im Modul wird das Promise abgelehnt.

Beispiele

Einfacher dynamischer Import mit await

// math.js (Modul):
// export const add = (a, b) => a + b;
// export default function multiply(a, b) { return a * b; }

// main.js
const loadMath = async () => {
  const math = await import('./math.js');

  console.log(math.add(3, 4));       // benannter Export
  console.log(math.default(3, 4));   // Default-Export über .default
};

loadMath();
7 12

Lazy Loading bei Nutzerinteraktion

// Das schwere Chart-Modul wird nur geladen, wenn der Button geklickt wird
document.getElementById('showChart').addEventListener('click', async () => {
  const { renderChart } = await import('./chartLibrary.js');
  renderChart(document.getElementById('canvas'), { data: [1, 2, 3, 5, 8] });
  console.log('Chart-Bibliothek geladen und Chart gerendert.');
});
Chart-Bibliothek geladen und Chart gerendert.

Dynamischer Modulpfad (z. B. Lokalisierung)

const loadLocale = async (lang) => {
  try {
    const { messages } = await import(`./locales/${lang}.js`);
    console.log(messages.greeting);
  } catch (err) {
    console.error(`Sprache '${lang}' konnte nicht geladen werden:`, err.message);
  }
};

await loadLocale('de'); // lädt ./locales/de.js
Hallo, Welt!

Destrukturierung direkt beim Import

// Benannte Exporte direkt destrukturieren
const { formatDate, formatCurrency } = await import('./formatters.js');

console.log(formatDate(new Date('2024-06-01')));   // '01.06.2024'
console.log(formatCurrency(1234.5, 'EUR'));         // '1.234,50 €'
01.06.2024 1.234,50 €

// Wichtig · Fallstricke

Kein echter Funktionsaufruf: Obwohl import() wie eine Funktion aussieht, ist es ein Sprachoperator. Der Ausdruck const dynamicImport = import; dynamicImport('./foo.js') ist daher ungültig – import kann nicht als Wert gespeichert oder übergeben werden.

  • Sicherheit bei dynamischen Pfaden: Wenn der Modulpfad aus Nutzereingaben zusammengesetzt wird, besteht ein Risiko für Path-Traversal-Angriffe. Pfade sollten immer validiert und gegen eine Whitelist geprüft werden.
  • Browser-Kompatibilität: Alle modernen Browser (Chrome 63+, Firefox 67+, Safari 11.1+, Edge 79+) sowie Node.js ab Version 12 unterstützen dynamische Imports. Internet Explorer unterstützt import() nicht.
  • Top-Level await: In Modulen (type="module") kann await import() direkt auf oberster Ebene verwendet werden (ES2022 Top-Level Await). In klassischen Skripten muss import() in einer async-Funktion genutzt werden.
  • Import-Assertions / Import Attributes: Die Syntax import('./data.json', { assert: { type: 'json' } }) (Chrome 91+) bzw. import('./data.json', { with: { type: 'json' } }) (neuerer Standard) erlaubt das Laden von JSON-Modulen. Die Unterstützung variiert je nach Browser und Laufzeit.
  • Caching: Module werden nach dem ersten Laden vom Browser gecacht. Mehrfache import()-Aufrufe mit demselben Pfad liefern dasselbe Modul-Namespace-Objekt zurück.