Unerwarteten Token-Export erhalten


220

Ich versuche, ES6-Code in meinem Projekt auszuführen, erhalte jedoch einen unerwarteten Fehler beim Token-Export.

export class MyClass {
  constructor() {
    console.log("es6");
  }
}

5
Es gibt nicht genügend Informationen zu Ihrer Umgebung oder Konfiguration, um Unterstützung zu bieten. Dieser Fehler deutet darauf hin, dass entweder Webpack oder Babel nicht ordnungsgemäß funktionieren, wie dies exportnur in ES6 verfügbar ist, und diese Module bieten ES6-Unterstützung.
Claies

24
Sie sollten verwenden module.exports = MyClass, nichtexport class MyClass
onmyway133

Antworten:


249

Sie verwenden die ES6-Modulsyntax.

Dies bedeutet, dass Ihre Umgebung (z. B. node.js) die Syntax des ES6-Moduls unterstützen muss.

NodeJS verwendet die CommonJS-Modulsyntax ( module.exports) und nicht die ES6- Modulsyntax ( exportSchlüsselwort).

Lösung:

  • Verwenden Sie das babelnpm-Paket, um Ihren ES6 auf ein commonjsZiel zu übertragen

oder

  • Refactor mit CommonJS-Syntax.

Beispiele für die CommonJS-Syntax sind (von flaviocopes.com/commonjs/ ):

  • exports.uppercase = str => str.toUpperCase()
  • exports.a = 1

15
Wann wird nodejs importnativ unterstützen? Ich dachte v10.0.0 hätte es aber anscheinend nicht.
Chovy

4
@chovy experimentelle Unterstützung ist mit dem Flag "--experimental-modules" verfügbar. Dateien müssen eine .mjs-Erweiterung haben
Giovanni P.

1
Ich erhalte diesen Fehler bei Verwendung von Chrome 66 mit nativer Unterstützung für Module.
Tom Russell

Übrigens: Beachten Sie, dass Node10 / Node12 zwar Module hinter dem Flag unterstützen, diese jedoch im REPL-Modus nicht unterstützen, jedoch im Eval-Modus in Node12 .
Jakub.g

2
Für jemanden ist immer noch nicht klar über CommonJs Syntax. Bitte überprüfen Sie diesen Link, kann ein wenig helfen. flaviocopes.com/commonjs
LT

142

Falls Sie diesen Fehler erhalten, hängt dies möglicherweise auch damit zusammen, wie Sie die Javascript-Datei in Ihre HTML-Seite aufgenommen haben. Beim Laden von Modulen müssen Sie diese Dateien explizit als solche deklarieren. Hier ein Beispiel:

//module.js:
function foo(){
   return "foo";
}

var bar = "bar";

export { foo, bar };

Wenn Sie das Skript wie folgt einfügen:

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

Sie erhalten den Fehler:

Nicht erfasster SyntaxError: Unerwarteter Token-Export

Sie müssen die Datei mit einem auf "Modul" gesetzten Typattribut einschließen:

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

Und dann funktioniert es wie erwartet und Sie können Ihr Modul in ein anderes Modul importieren:

import { foo, bar } from  "./module.js";

console.log( foo() );
console.log( bar );

37
Im Gegensatz zur "am besten bewerteten" Antwort löst dies das Problem tatsächlich und erklärt, warum dies geschieht, ohne darauf hinzuweisen, dass die einzige Option darin besteht, eine CommonJS-Methode oder eine APM-Methode zu nutzen oder unseren Code zu transpilieren ... Dies wäre auch eine Ausnahme nach dem w3c-Standard, bei typedem ein gültiger MIME- Typ (auch bekannt als Medientyp) erwartet wird, war dies ein unerwarteter Fund. Vielen Dank!
Shaun Wilson

4
Dies behebt den Fehler, aber ich erhalte dann "Unerwartetes Token {" in der Zeile der Importanweisung in Chrome 67 mit einem Inline-Skript, z. B. <script> import ... </ script>
PandaWood

1
@PandaWood Sie müssen verwenden <script type="module">import ...</script>, wenn Sie aus dem Modul importieren. Ich habe es in der neuesten Version von Chromium getestet.
Vladimir S.

Dies hat mein Problem behoben :)
user3651476

Pure JS (ES6) hat den Import unterstützt und dies erklärt genau, warum ich dies getroffen habe
Eric

15

Meine zwei Cent

Export

ES6

myClass.js

export class MyClass1 {
}
export class MyClass2 {
}

other.js

import { MyClass1, MyClass2 } from './myClass';

CommonJS Alternative

myClass.js

class MyClass1 {
}
class MyClass2 {
}
module.exports = { MyClass1, MyClass2 }
// or
// exports = { MyClass1, MyClass2 };

other.js

const { MyClass1, MyClass2 } = require('./myClass');

Standard exportieren

ES6

myClass.js

export default class MyClass {
}

other.js

import MyClass from './myClass';

CommonJS Alternative

myClass.js

module.exports = class MyClass1 {
}

other.js

const MyClass = require('./myClass');

Hoffe das hilft


Für das ES6-Standardexportbeispiel haben Sie "Standardexport" geschrieben, es sollte jedoch "Standardexport exportieren" sein.
IAM_AL_X

@IAM_AL_X Danke für den Fang :-)
Barnstokkr

10

Um ES6 zu verwenden, fügen Sie hinzu babel-preset-env

und in deinem .babelrc:

{
  "presets": ["@babel/preset-env"]
}

Antwort aktualisiert dank @ghanbari Kommentar, um babel 7 anzuwenden.


8
seine Frage nicht über die Erklärung von Babel. Warum sollte die Beantwortung von etwas nicht erforderlich sein, was andere verwirren könnte?
Jalal

7
@monsto diese Frage wurde bereits babelvom Autor getaggt . Während Phil Ricketts Antwort das Problem klarstellt, was gut ist, ist diese Antwort eine direkte Lösung für das Problem des Autors.
Boycy

"@ babel /
preset

6

Babel muss derzeit nicht verwendet werden (JS ist sehr leistungsfähig geworden), wenn Sie einfach die Standard-JavaScript-Modulexporte verwenden können. Überprüfen Sie das vollständige Tutorial

Message.js

module.exports = 'Hello world';

app.js.

var msg = require('./Messages.js');

console.log(msg); // Hello World

2
Wie würden Sie dann eine Klasse exportieren?
Sherwin Ablaña Dapito

1
Ich lösche meine Antwort, da die Frage tatsächlich für ES6 und nicht für CommonJS war, das von NodeJS verwendet wird. Bitte überprüfen Sie oben für eine Antwort.
Alvin Konda

@ SherwinAblañaDapito module.exports = class MyClass {} works
Marian Klühspies

3

Installieren Sie die babel - Pakete @babel/coreund @babel/presetdie konvertiert ES6 zu einem Commonjs Ziel als Knoten js nicht versteht ES6 Ziele direkt

npm install --save-dev @babel/core @babel/preset-env

Anschließend müssen Sie eine Konfigurationsdatei mit dem Namen .babelrcim Stammverzeichnis Ihres Projekts erstellen und diesen Code dort hinzufügen

{ "presets": ["@babel/preset-env"] }


Ich musste auch @ babel / register installieren, sonst würde ich immer noch "SyntaxError: Importanweisung kann nicht außerhalb eines Moduls verwendet werden"
Molecular

3

Ich habe dies behoben, indem ich eine Einstiegspunktdatei wie erstellt habe.

// index.js
require = require('esm')(module)
module.exports = require('./app.js')

und jede Datei, die ich innerhalb app.jsund außerhalb importiert habe, hat imports/exports jetzt funktioniert. Sie führen sie einfach so ausnode index.js

Hinweis: Wenn app.jsverwendet export default, wird dies require('./app.js').defaultbei Verwendung der Einstiegspunktdatei.


1
Beste Antwort für einfache Projekte ohne Babel, Webpack, Paket usw. Ich habe in Monorepo-Projekt mit Simple / Server Express für Projekt verwendet. Arbeitete wie ein Zauber ...
Mattdlockyer

-3

Die Verwendung der ES6-Syntax funktioniert im Knoten nicht. Leider muss babel anscheinend vorhanden sein, damit der Compiler die Syntax wie Export oder Import versteht.

npm install babel-cli --save

Jetzt müssen wir eine .babelrc-Datei erstellen. In der babelrc-Datei setzen wir babel so, dass beim Kompilieren auf ES5 die Voreinstellung es2015 verwendet wird, die wir als Voreinstellung installiert haben.

Im Stammverzeichnis unserer App erstellen wir eine .babelrc-Datei. $ npm install babel-preset-es2015 --save

Im Stammverzeichnis unserer App erstellen wir eine .babelrc-Datei.

{  "presets": ["es2015"] }

Hoffe, es funktioniert ... :)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.