Die Fehlermeldung „Cannot use import statement outside a module“ tritt auf, wenn das Schlüsselwort import in einem nicht ordnungsgemäß konfigurierten JavaScript- oder TypeScript-Modul vorkommt.

In einer serverseitigen JavaScript-Laufzeitumgebung resultiert dieser Fehler in der Regel aus der Verwendung der import -Syntax für Module, die in ECMAScript (ES) geschrieben wurden, während Node.js das require -Schlüsselwort erwartet, das vom CommonJS-Modulsystem verwendet wird.

TypeScript unterstützt verschiedene Modulformate, aber Codierungsfehler, die den ES- und den CommonJS-Ansatz für den Import von Modulen verwechseln, führen ebenfalls zu diesem Fehler.

Auf der Browserseite tritt der Fehler typischerweise auf, wenn du keinen Bundler für deine JavaScript-Code-Dateien verwendest.

Dieser Artikel befasst sich mit diesen drei Fehlerquellen und zeigt eine Lösung für jede Umgebung auf.

So behebst du den Fehler in serverseitigem JavaScript

In diesem Abschnitt wird gezeigt, wie der Fehler in serverseitigen JavaScript-Umgebungen behoben werden kann.

Hintergrund

Node.js verwendet standardmäßig das Schlüsselwort require des CommonJS-Systems. Daher erhältst du die bekannte Fehlermeldung, wenn du Node.js nicht so konfigurierst, dass es die Syntax von ES-Modulen unterstützt. Außerdem benötigt Node.js die Erweiterung .mjs, um ES-Module zu erkennen und mit ihnen zu arbeiten.

Lösung

Als Alternative zur Verwendung von .mjs kannst du ältere Versionen von Node.js mit dem aktuellen ES-Modul kompatibel machen, indem du Bundler verwendest oder Node.js mit dem --experimental-modules Flag ausführst. Andernfalls kannst du das Feld type in der Datei package.json wie folgt auf module setzen:

{
  "name": "test-package",
  "version": "1.0.0",
  "type": "module",
  "main": "app.js",
  "dependencies": { }
}

(Hinweis: Du solltest die Eigenschaft type in der package.json-Datei in alle Pakete aufnehmen. So kannst du das verwendete Modulsystem leichter identifizieren und die Konsistenz zwischen deinen Bibliotheken sicherstellen)

Eine weitere Möglichkeit, den Fehler zu vermeiden, ist sicherzustellen, dass die Syntaxen import und export korrekt sind und richtig geladen werden. Es ist wichtig, dass du immer relative Dateipfade, benannte Exporte und Dateierweiterungen für Exporte verwendest und Standardexporte vermeidest.

Hier ist ein Beispiel:

//module import 
import { sampleFunction } from './sampleModule.js';

// function export
export function sampleFunction() {
     // code goes here
}

Schließlich solltest du sicherstellen, dass alle Bibliotheken von Drittanbietern mit den ES-Modulen kompatibel sind. Diese Informationen findest du in der Dokumentation der Bibliothek in der package.json-Datei. Alternativ kannst du einen Bundler verwenden, um den Code zu transpilieren, damit eine JavaScript-Umgebung ihn verstehen kann.

Wie man den Fehler in TypeScript-Umgebungen behebt

In diesem Abschnitt wird gezeigt, wie die Fehlermeldung in TypeScript-Umgebungen behoben wird.

Hintergrund

Mit Modulen kannst du Code wiederverwenden, organisieren und für mehrere Dateien in einem Projekt freigeben. ES unterstützt externe Module zur gemeinsamen Nutzung von Code in verschiedenen Dateien mit den Schlüsselwörtern import und export.

Dieser Fehler tritt in der Regel in TypeScript-Umgebungen auf, wenn die ES-Modulsyntax verwendet wird, ohne dass TypeScript für die Verwendung konfiguriert wurde. Da TypeScript eine Obermenge von JavaScript ist, verwendet es standardmäßig die CommonJS-Syntax für Importe, die require anstelle von import verwendet. In diesem Fall verursacht die Anweisung import den Fehler. Damit TypeScript ES-Module unterstützen kann, muss es jedoch korrekt konfiguriert werden.

Dieser Fehler kann auch auftreten, wenn du die falsche Dateierweiterung verwendest. Wenn du TypeScript zum Beispiel in einer Node.js-Umgebung mit ES-Modulsyntax verwendest, muss das Modul, das du importieren willst, die Dateierweiterung .mjs haben und nicht die normale .js.

Eine weitere häufige Fehlerquelle ist die unsachgemäße Konfiguration des module Feldes in deiner tsconfig.json oder package.json Datei, wenn du Bundler wie Webpack verwendest. Du kannst jedoch Bundler für ES-Module in TypeScript verwenden, indem du die Felder module und target in der tsconfig.json-Datei auf ECMAScript setzt. Dann versteht Webpack die Zielumgebung und verwendet beim Transpilieren des Codes die richtigen Dateierweiterungen.

Lösung

Um ES-Module mit einem Modullader wie RequireJS oder einem Bundler wie Webpack zu laden, musst du die Datei tsconfig.json wie folgt ergänzen:

{
  "compilerOptions": {
    "module": "es20215",
    "target": "es20215",
    "sourceMap": true
  }
}

Im compilerOptions Teil des obigen Codes werden die Felder module und target so eingestellt, dass ein es20215 Modul verwendet wird. Mit diesen Ergänzungen kannst du die Anweisungen import und export in einer TypeScript-Umgebung verwenden, ohne dass der Fehler auftritt.

Da TypeScript standardmäßig CommonJS verwendet, wird die Fehlermeldung angezeigt, wenn du die Datei tsconfig.json nicht entsprechend anpasst.

Wenn du die Felder module und target so eingestellt hast, dass ein ECMAScript Modul verwendet wird, kannst du die Anweisung export verwenden, um eine Funktion oder Variable aus einem Modul zu exportieren, und die Anweisung import, um ein anderes Modul in den Geltungsbereich des aktuellen Moduls zu laden. Dieser Vorgang findet im folgenden Code statt:

// sum.ts
export function sum(a: number, b: number, c: number): number {
  return a + b + c;
}

// main.ts
import { sum } from './sum';
console.log(add(4, 4, 9));

Wenn du eine ältere Version von Node.js verwendest, kannst du die ES-Modulunterstützung aktivieren, indem du deinen Code mit dem --experimental-modules Flag ausführst. Du solltest auch einen Bundler wie Webpack, Browserify oder Rollup verwenden, um den gesamten ES-Code zu bündeln und in einer einzigen Datei auszugeben. Achte darauf, dass er in einer Version vorliegt, die von Browsern und alten Node.js-Versionen verstanden wird, und lege eine Webpack.config.js-Datei im Stammverzeichnis deines Projekts an, die den Modultyp angibt.

Hier ist ein Beispiel aus der Webpack-Dokumentation:

module.exports = {
  entry: './src/index.ts',
  output: {
    filename: 'bundle.js',
   path: path.resolve(__dirname, 'dist')
  },
  resolve: {
    extensions: ['.ts', '.js', '.mjs']
  },
  module: {
    rules: [
      {
        test: /.ts$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  experiments: {
    outputModule: true
  }
};

Der kompilierte Code wird in einer bundle.js-Datei im dist-Verzeichnis des Stammverzeichnisses des Projekts ausgegeben.

Du kannst auch Polyfills wie es-module-shims verwenden, um ältere Browser anzusprechen, die die Anweisungen import und export der ES-Module nicht unterstützen.

So behebst du den Fehler in browser-seitigem JavaScript

Dieser Abschnitt zeigt dir, wie du den Fehler in browserbasierten JavaScript-Umgebungen beheben kannst.

Hintergrund

Die meisten modernen Browser, darunter Chrome, Firefox, Edge und Safari, unterstützen ES-Module, sodass du keine Browser-Polyfills, Bundler oder Transpiler verwenden musst.

Du brauchst sie auch nicht, wenn du die JavaScript-basierten Frontend-Bibliotheken von React oder Vue verwendest, da diese standardmäßig die ES imports und exports Felder unterstützen. Ältere Browser unterstützen die ES-Syntax jedoch nicht, sodass sie diese Tools für die plattformübergreifende Kompatibilität benötigen.

Der häufigste Grund für den Fehler in älteren Browsern ist, dass die HTML-Dateien einer Seite das Attribut type="module" nicht enthalten. In diesem Fall tritt der Fehler auf, weil JavaScript im Web keine Standardunterstützung für die Syntax des ES-Moduls enthält. Bei JavaScript-Code, der über das Internet gesendet wird, kann ein Fehler bei der gemeinsamen Nutzung von Ressourcen auftreten, wenn du versuchst, ein ES-Modul von einer anderen Domain zu laden.

Lösung

Um den Modulfehler in einem älteren Browser zu vermeiden, stelle sicher, dass du das richtige script Tag-Attribut – type="module" – in der Root-HTML-Datei verwendest. Alternativ kannst du Webpack verwenden, um den Code so zu transpilieren, dass ältere Browser ihn verstehen können.

Um das Attribut type="module" zu verwenden, füge die folgende Zeile in deine Root-HTML-Datei ein:

<script type="module" src="app.js"></script>

Du musst auch sicherstellen, dass die import Dateipfade gültig sind und dass du die richtige import Syntax verwendest.

Außerdem kannst du dich auf Websites wie Can I Use über die Browserkompatibilität von ES-Modulen informieren.

Da die Verwendung der .js-Dateierweiterung gängige Praxis ist, kannst du das type -Attribut im script -Tag der HTML-Datei des Moduls als Abhilfe setzen. Wenn du dieses Attribut auf module setzt, wird der Browser die .js-Erweiterung ignorieren und die Datei als Modul behandeln.

Zusammenfassung

Der Fehler „Cannot use import statement outside a module“ kann aus verschiedenen Gründen auftreten, je nachdem, ob du in einer browser- oder serverseitigen JavaScript-Umgebung arbeitest. Falsche Syntax, ungeeignete Konfigurationen und nicht unterstützte Dateierweiterungen sind einige der häufigsten Ursachen für diesen Fehler.

Während die meisten modernen Browser ES-Module unterstützen, musst du sicherstellen, dass ältere Browser kompatibel sind. Bundler wie Webpack ermöglichen es dir, den gesamten Quellcode mit seinen Abhängigkeiten zu einer einzigen Ausgabe zu kompilieren, die ältere Browser verstehen können.

Vergiss nicht, das type="module" -Attribut in die HTML-Datei einzufügen, um dem Browser mitzuteilen, dass das Modul ein ES-Modul ist. Während die Verwendung der .js-Erweiterung für CommonJS die Standardpraxis ist, kannst du auch die .mjs-Erweiterung verwenden, um den Import von ES-Modulen zu ermöglichen.

Hast du eine JavaScript-Anwendung, die du online stellen musst, aber du willst die Server nicht selbst verwalten? Dann könnten die Plattformen Anwendungs-Hosting und Datenbank-Hosting von Kinsta die richtige Lösung sein. Du könntest diese Dienste sogar mit Kinstas Statischem Seiten Hosting kombinieren, um das Frontend deiner Anwendung kostenlos zur Verfügung zu stellen.