Start · Sprachen · JavaScript · Referenz · import.source()

import.source()

Keyword

Lädt ein Modul wie <code>import()</code>, gibt aber ein Promise für ein Objekt zurück, das den kompilierten, noch nicht verknüpften Quellcode darstellt, z. B. ein <code>WebAssembly.Module</code>.

seit JavaScript TC39-Proposal „Source Phase Imports“ (Stage 3); ex Kategorie: syntax

Signatur

import.source(moduleName, options)

Beschreibung

import.source() ist die dynamische Form der Source-Phase-Imports. Wie beim normalen import() wird der Modulbezeichner aufgelöst, die Ressource geladen und kompiliert. Das Modul wird aber nicht verknüpft und nicht ausgeführt. Das Promise erfüllt sich stattdessen mit einem Quellobjekt, das den kompilierten Code darstellt. Bei WebAssembly ist das ein WebAssembly.Module.

Das ist sinnvoll, wenn man selbst bestimmen will, wie und wie oft ein Modul instanziiert wird, zum Beispiel:

  • Ein WebAssembly-Modul mit eigenen Import-Objekten instanziieren, statt die ESM-Integration die Imports auflösen zu lassen.
  • Dasselbe kompilierte Modul mehrfach instanziieren, etwa für isolierte Speicherbereiche.
  • Ein kompiliertes Modul per postMessage() an einen Worker übergeben.

Die Modulauflösung läuft über das Modulsystem des Hosts. Deshalb gelten Import Maps, Bundler-Analyse, CSP-Regeln und der Modul-Cache genauso wie bei import(). Das ersetzt die bisher nötigen, schlecht analysierbaren Muster mit fetch() und new URL(..., import.meta.url). Die statische Entsprechung lautet import source name from "specifier".

Welcher Objekttyp zurückkommt, hängt vom Modultyp ab. Derzeit ist nur WebAssembly definiert. Für normale JavaScript-Module gibt es noch keine Quelldarstellung, dort wird das Promise mit einem SyntaxError abgelehnt.

Parameter

Name Typ Default Beschreibung
$moduleName Pflicht string Modulbezeichner, genau wie bei import(): relativer Pfad, absolute URL oder über Import Maps bzw. node_modules auflösbarer Name, z. B. "./rechner.wasm".
$options object undefined Optionale Import-Optionen wie bei import(), z. B. { with: { ... } } für Import-Attribute. Ob das unterstützt wird, hängt von der Laufzeitumgebung ab.

Rückgabewert

Typ
Promise<WebAssembly.Module | object>
Beschreibung
Ein Promise, das sich mit dem Quellobjekt des Moduls erfüllt. Bei .wasm ist das ein WebAssembly.Module. Das Promise wird abgelehnt, wenn das Laden oder Kompilieren fehlschlägt oder wenn der Modultyp keine Quelldarstellung hat (SyntaxError).

Beispiele

WebAssembly-Modul laden und mit eigenen Imports instanziieren

// rechner.wasm exportiert add(a, b) und importiert env.log
const wasmModule = await import.source("./rechner.wasm");

console.log(wasmModule instanceof WebAssembly.Module);

const instance = await WebAssembly.instantiate(wasmModule, {
  env: { log: (wert) => console.log("WASM sagt:", wert) },
});

console.log(instance.exports.add(2, 3));
true 5

Kompiliertes Modul einmal laden, mehrfach instanziieren

const quelle = await import.source("./zaehler.wasm");

// Zwei unabhängige Instanzen mit eigenem Zustand
const [a, b] = await Promise.all([
  WebAssembly.instantiate(quelle, {}),
  WebAssembly.instantiate(quelle, {}),
]);

a.exports.increment();
a.exports.increment();
b.exports.increment();

console.log(a.exports.get(), b.exports.get());
2 1

Modul an einen Worker übergeben

// main.js
const modul = await import.source("./bildfilter.wasm");
const worker = new Worker(new URL("./worker.js", import.meta.url), { type: "module" });
worker.postMessage({ modul }); // WebAssembly.Module ist klonbar

// worker.js
self.onmessage = async ({ data }) => {
  const instance = await WebAssembly.instantiate(data.modul, {});
  self.postMessage(instance.exports.version());
};

Fehlerbehandlung und Rückfall auf fetch()

const ladeWasm = async (pfad) => {
  try {
    return await import.source(pfad);
  } catch (err) {
    // SyntaxError, falls die Umgebung import.source nicht kennt,
    // ist hier NICHT abfangbar – siehe Hinweise.
    console.warn("Source-Import fehlgeschlagen:", err.name);
    return WebAssembly.compileStreaming(fetch(pfad));
  }
};

const modul = await ladeWasm("./rechner.wasm");
console.log(WebAssembly.Module.exports(modul).map((e) => e.name));
["add"]

// Wichtig · Fallstricke

  • Experimentell: Das Proposal ist auf Stage 3 und noch nicht in allen Umgebungen verfügbar. Deno 2 unterstützt es. Node.js ab Version 24 unterstützt es mit --experimental-wasm-modules. In Browsern ist es teils nur hinter Flags verfügbar. Prüfe vor dem Einsatz die aktuelle Kompatibilität oder nutze einen Bundler, der die Syntax umsetzt.
  • Syntax-Erkennung: Kennt eine Engine import.source nicht, ist das ein Parse-Fehler. Das ganze Skript schlägt dann fehl, und ein try/catch hilft nicht. Eine Feature-Erkennung geht nur über getrennte Module oder new Function().
  • Nur für bestimmte Modultypen: Derzeit ist nur WebAssembly definiert. Bei einem JavaScript-Modul wird das Promise mit SyntaxError abgelehnt.
  • Das Modul wird nicht ausgeführt. Nebenwirkungen und Top-Level-Code laufen erst, wenn du es selbst instanziierst.
  • import.source ist keine Funktion. Man kann es nicht in eine Variable schreiben, nicht mit .call() aufrufen und nicht weitergeben.
  • Sicherheit: Es gelten dieselben CORS- und CSP-Regeln wie bei import(). Für WebAssembly kann zusätzlich 'wasm-unsafe-eval' in der CSP nötig sein.