Obteniendo exportación de tokens inesperados

221

Estoy tratando de ejecutar algún código ES6 en mi proyecto, pero recibo un error inesperado de exportación de token.

export class MyClass {
  constructor() {
    console.log("es6");
  }
}
Jason
fuente
55
no hay suficiente información sobre su entorno o configuración para ofrecer asistencia. Este error sugiere que webpack o babel no funcionan correctamente, ya exportque solo está disponible en ES6, y esos módulos son los que proporcionan soporte para ES6.
Claies
24
Deberías usar module.exports = MyClass, noexport class MyClass
onmyway133

Respuestas:

249

Está utilizando la sintaxis del módulo ES6.

Esto significa que su entorno (por ejemplo, node.js) debe admitir la sintaxis del módulo ES6.

NodeJS usa la sintaxis del módulo CommonJS ( module.exports) no la sintaxis del módulo ES6 ( exportpalabra clave).

Solución:

  • Use el babelpaquete npm para transpilar su ES6 a un commonjsobjetivo

o

  • Refactorizador con sintaxis CommonJS.

Ejemplos de sintaxis de CommonJS son (de flaviocopes.com/commonjs/ ):

  • exports.uppercase = str => str.toUpperCase()
  • exports.a = 1
Phil Ricketts
fuente
15
¿Cuándo soportará nodejs de importforma nativa? Pensé que v10.0.0 lo tendría, pero aparentemente no.
chovy
44
El soporte experimental @chovy está disponible con la marca "--experimental-modules". Los archivos deben tener una extensión .mjs
Giovanni P.
1
Recibo este error usando Chrome 66 con soporte nativo para módulos.
Tom Russell
Por cierto: tenga en cuenta que si bien los módulos de soporte node10 / node12 detrás del indicador, no lo admiten en modo REPL; sin embargo, sí lo es en modo eval en nodo12 .
jakub.g
2
Para alguien todavía no está claro acerca de la sintaxis de CommonJs. por favor revise este enlace, puede ayudar un poco. flaviocopes.com/commonjs
LT
142

En caso de que reciba este error, también podría estar relacionado con la forma en que incluyó el archivo javascript en su página html. Al cargar módulos, debe declarar explícitamente esos archivos como tales. Aquí un ejemplo:

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

var bar = "bar";

export { foo, bar };

Cuando incluye el script de esta manera:

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

Obtendrás el error:

SyntaxError no capturado: exportación de token inesperada

Debe incluir el archivo con un atributo de tipo establecido en "módulo":

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

Y luego funcionará como se espera y estará listo para importar su módulo en otro módulo:

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

console.log( foo() );
console.log( bar );
Marchitar
fuente
37
a diferencia de la respuesta "más votada", esto realmente resuelve el problema y explica por qué está sucediendo sin sugerir que la única opción es aprovechar un método CommonJS, un método APM o transpilar nuestro código ... Esto también sería una excepción para el estándar w3c donde typese espera que sea un tipo mime válido (también conocido como tipo de medio), por lo que este fue un hallazgo inesperado. ¡Gracias!
Shaun Wilson
44
Esto corrige el error, pero luego obtengo un "token inesperado {" en la línea de la declaración de importación en Chrome 67 con un script que está en línea, por ejemplo, <script> import ... </script>
PandaWood
1
@PandaWood Tienes que usar <script type="module">import ...</script>, cuando importas desde el módulo. Lo probé en una versión reciente de Chromium.
Vladimir S.
Esto solucionó mi problema :)
user3651476
Pure JS (ES6) ha admitido la importación y esto explica exactamente por qué lo conocí
Eric
16

Mis dos centavos

Exportar

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');

Exportar predeterminado

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');

Espero que esto ayude

Barnstokkr
fuente
Para el ejemplo de exportación predeterminada de ES6, escribió "exportación predeterminada", pero debería ser "exportación predeterminada".
IAM_AL_X
@IAM_AL_X Gracias por la captura :-)
Barnstokkr
10

Para usar ES6 agregue babel-preset-env

y en tu .babelrc:

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

Respuesta actualizada gracias al comentario de @ghanbari para aplicar babel 7.

Jalal
fuente
8
su pregunta no se trata de explicar babel. Entonces, ¿por qué responder algo no requerido que puede confundir a otros?
Jalal
77
@monsto esta pregunta ya fue etiquetada babelpor el autor. Si bien la respuesta de Phil Ricketts aclara el problema, lo cual es bueno, esta respuesta es una solución directa al problema del autor.
boycy
"@ babel / preset-env"
ghanbari
6

No hay necesidad de usar Babel en este momento (JS se ha vuelto muy poderoso) cuando simplemente puede usar las exportaciones predeterminadas del módulo JavaScript. Ver tutorial completo

Message.js

module.exports = 'Hello world';

app.js

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

console.log(msg); // Hello World
Alvin Konda
fuente
2
Bueno, ¿cómo exportarías una clase entonces?
Sherwin Ablaña Dapito
1
Estoy borrando mi respuesta ya que la pregunta era de hecho para ES6 y no para CommonJS utilizada por NodeJS. Por favor, consulte más arriba para obtener una respuesta.
Alvin Konda
@ SherwinAblañaDapito module.exports = class MyClass {} funciona
Marian Klühspies
3

Instale los paquetes de babel @babel/corey @babel/presetque convertirá ES6 en un objetivo commonjs ya que el nodo js no entiende los objetivos ES6 directamente

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

Luego, debe crear un archivo de configuración con el nombre .babelrcen el directorio raíz de su proyecto y agregar este código allí

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

YouBee
fuente
También necesitaba instalar @ babel / register, de lo contrario aún obtendría "SyntaxError: No se puede usar la declaración de importación fuera de un módulo"
molecular
3

Lo arreglé haciendo un archivo de punto de entrada como.

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

y cualquier archivo que importé dentro app.jsy más allá funcionó imports/exports ahora solo lo ejecuta comonode index.js

Nota: si se app.jsusa export default, esto se hace require('./app.js').defaultcuando se usa el archivo de punto de entrada.

Alex Cory
fuente
1
La mejor respuesta para proyectos simples que no necesitan babel, paquete web, paquete, etc. Utilicé en proyecto monorepo con simple / server express para proyecto. Trabajó como un encanto ...
mattdlockyer
-3

El uso de la sintaxis ES6 no funciona en el nodo, desafortunadamente, aparentemente debe tener babel para que el compilador entienda la sintaxis como exportar o importar.

npm install babel-cli --save

Ahora necesitamos crear un archivo .babelrc, en el archivo babelrc, configuraremos a babel para que use el preajuste es2015 que instalamos como preajuste al compilar en ES5.

En la raíz de nuestra aplicación, crearemos un archivo .babelrc. $ npm install babel-preset-es2015 --save

En la raíz de nuestra aplicación, crearemos un archivo .babelrc.

{  "presets": ["es2015"] }

Espero que funcione ... :)

purushottam banerjee
fuente