Ottenere l'esportazione token imprevista


221

Sto cercando di eseguire un po 'di codice ES6 nel mio progetto ma sto ricevendo un errore di esportazione di token imprevisto.

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

5
non ci sono abbastanza informazioni sull'ambiente o sulla configurazione per offrire assistenza. Questo errore suggerisce che Webpack o Babel non funzionano correttamente, poiché exportè disponibile solo in ES6 e questi moduli sono ciò che fornisce il supporto ES6.
Claies,

24
Dovresti usare module.exports = MyClass, nonexport class MyClass
onmyway133

Risposte:


249

Si sta utilizzando la sintassi del modulo ES6.

Ciò significa che l'ambiente (ad esempio node.js) deve supportare la sintassi del modulo ES6.

NodeJS utilizza la sintassi del modulo CommonJS ( module.exports) e non la sintassi del modulo ES6 ( exportparola chiave).

Soluzione:

  • Usa il babelpacchetto npm per compilare il tuo ES6 su un commonjstarget

o

  • Refactor con sintassi CommonJS.

Esempi di sintassi CommonJS sono (da flaviocopes.com/commonjs/ ):

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

15
Quando sarà supportato nodejs in importmodo nativo? Pensavo che la v10.0.0 l'avrebbe, ma apparentemente no.
Chovy

4
Il supporto sperimentale di @chovy è disponibile con flag "--experimental-modules". I file devono avere l'estensione .mjs
Giovanni P.

1
Ricevo questo errore utilizzando Chrome 66 con supporto nativo per i moduli.
Tom Russell,

A proposito: nota che mentre node10 / node12 supportano i moduli dietro il flag, non lo supportano in modalità REPL - tuttavia è supportato in modalità eval in node12 .
jakub.g,

2
Per qualcuno non sono ancora chiari sulla sintassi di CommonJs. controlla questo link, potrebbe essere di aiuto. flaviocopes.com/commonjs
LT

142

Nel caso in cui venga visualizzato questo errore, potrebbe anche essere correlato al modo in cui hai incluso il file javascript nella tua pagina html. Quando si caricano i moduli, è necessario dichiarare esplicitamente tali file come tali. Ecco un esempio:

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

var bar = "bar";

export { foo, bar };

Quando includi lo script in questo modo:

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

Riceverai l'errore:

Uncaught SyntaxError: esportazione token imprevista

Devi includere il file con un attributo type impostato su "module":

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

Quindi funzionerà come previsto e sei pronto per importare il tuo modulo in un altro modulo:

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

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

37
a differenza della risposta "più votata", questo in realtà risolve il problema e spiega perché sta accadendo senza suggerire che l'unica opzione è quella di sfruttare un metodo CommonJS, un metodo APM o traspilare il nostro codice ... Questa sarebbe anche un'eccezione allo standard w3c dove typeci si aspetta che sia un tipo mime valido (aka. tipo di media), quindi questa è stata una scoperta inaspettata. Grazie!
Shaun Wilson,

4
Questo risolve l'errore ma ricevo "Token imprevisto {" sulla riga
dell'istruzione

1
@PandaWood Devi <script type="module">import ...</script>importare quando importi dal modulo. L'ho provato nella recente versione di Chromium.
Vladimir S.

Questo risolto il mio problema :)
user3651476

Pure JS (ES6) ha supportato l'importazione e questo spiega esattamente perché l'ho incontrato
Eric

16

I miei due centesimi

Esportare

ES6

myClass.js

export class MyClass1 {
}
export class MyClass2 {
}

other.js

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

Alternativa CommonJS

myClass.js

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

other.js

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

Esporta predefinito

ES6

myClass.js

export default class MyClass {
}

other.js

import MyClass from './myClass';

Alternativa CommonJS

myClass.js

module.exports = class MyClass1 {
}

other.js

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

Spero che questo ti aiuti


Per l'esempio di esportazione predefinita ES6, hai scritto "esportazione predefinita", ma dovrebbe essere "esportazione predefinita".
IAM_AL_X

@IAM_AL_X Grazie per la cattura :-)
Barnstokkr

10

Per usare ES6 aggiungi babel-preset-env

e nel tuo .babelrc:

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

Risposta aggiornata grazie al commento di @ghanbari per applicare babel 7.


8
la sua domanda non era di spiegare la babele. Quindi perché rispondere a qualcosa di non necessario che potrebbe confondere gli altri?
Jalal,

7
@monsto questa domanda è già stata taggata babeldall'autore. Mentre la risposta di Phil Ricketts chiarisce il problema, il che è positivo, questa risposta è una soluzione diretta al problema dell'autore.
boycy

"@ babel / preset-env"
ghanbari,

6

Non è necessario utilizzare Babel in questo momento (JS è diventato molto potente) quando puoi semplicemente usare le esportazioni del modulo JavaScript predefinito. Controlla il tutorial completo

Message.js

module.exports = 'Hello world';

app.js

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

console.log(msg); // Hello World

2
Bene, come esporteresti una classe allora?
Sherwin Ablaña Dapito,

1
Sto cancellando la mia risposta poiché la domanda era in realtà per ES6 e non CommonJS utilizzato da NodeJS. Si prega di controllare sopra per una risposta.
Alvin Konda,

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

3

Installa i pacchetti babel @babel/coree @babel/presetquesto convertirà ES6 in un target commonjs poiché il nodo js non comprende direttamente i target ES6

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

Quindi è necessario creare un file di configurazione con nome .babelrcnella directory principale del progetto e aggiungere questo codice lì

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


Avevo anche bisogno di installare @ babel / register, altrimenti avrei comunque ricevuto "SyntaxError: impossibile usare la dichiarazione di importazione al di fuori di un modulo"
molecolare

3

Ho risolto questo problema creando un file del punto di ingresso simile.

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

e qualsiasi file che ho importato dentro app.jse fuori con cui imports/exports hai lavorato ora lo esegui comenode index.js

Nota: se app.jsutilizzato export default, questo diventa require('./app.js').defaultquando si utilizza il file del punto di ingresso.


1
La migliore risposta per progetti semplici che non richiedono babel, webpack, pacchi ecc ... Ho usato nel progetto monorepo con semplice / server express per il progetto. Ha funzionato come un fascino ...
mattdlockyer

-3

L'uso della sintassi ES6 non funziona nel nodo, sfortunatamente, devi avere babel apparentemente per far capire al compilatore la sintassi come export o import.

npm install babel-cli --save

Ora dobbiamo creare un file .babelrc, nel file babelrc, imposteremo babel per usare il predefinito es2015 che abbiamo installato come predefinito durante la compilazione su ES5.

Alla radice della nostra app, creeremo un file .babelrc. $ npm installa babel-preset-es2015 --save

Alla radice della nostra app, creeremo un file .babelrc.

{  "presets": ["es2015"] }

Spero funzioni ... :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.