SyntaxError: no se puede usar la declaración de importación fuera de un módulo

53

Tengo un proyecto ApolloServer que me está causando problemas, así que pensé que podría actualizarlo y me encontré con problemas al usar el último Babel. Mi "index.js" es:

require('dotenv').config()
import {startServer} from './server'
startServer()

Y cuando lo ejecuto me sale el error "SyntaxError: No se puede usar la declaración de importación fuera de un módulo". Primero intenté hacer cosas para convencer a TPTB * de que este era un módulo (sin éxito). Así que cambié la "importación" a "requerir" y esto funcionó.

Pero ahora tengo alrededor de dos docenas de "importaciones" en otros archivos que me dan el mismo error.

* Estoy seguro de que la raíz de mi problema es que ni siquiera estoy seguro de qué se está quejando del problema. Asumí que era Babel 7 (ya que vengo de Babel 6 y tuve que cambiar los ajustes preestablecidos), pero no estoy 100% seguro.

La mayor parte de lo que he encontrado para soluciones no parece aplicarse al Nodo directo. Como este aquí:

Importación del módulo ES6 dando "Error de sintaxis no detectado: identificador inesperado"

Dice que se resolvió agregando "type = module" pero esto normalmente iría en el HTML, del cual no tengo ninguno. También he intentado usar los preajustes antiguos de mi proyecto:

"presets": ["es2015", "stage-2"],
"plugins": []

Pero eso me da otro error: "Error: los archivos de Plugin / Preset no pueden exportar objetos, solo funciones".

ACTUALIZACIÓN: Aquí están las dependencias con las que comencé:

"dependencies": {
"@babel/polyfill": "^7.6.0",
"apollo-link-error": "^1.1.12",
"apollo-link-http": "^1.5.16",
"apollo-server": "^2.9.6",
"babel-preset-es2015": "^6.24.1",
usuario3810626
fuente
1
Hola, tengo el mismo problema ahora. ¿Podrías también compartir tus dependencias? Tal vez incluso una diferencia antes y después de su actualización. Podría verificar el mío para ver si podemos encontrar paquetes similares que puedan causar el problema.
lince
Acabo de reemplazar todas las "importaciones" con "requiere" y todo está bien ahora. Tonto, pero no valía la pena el esfuerzo de resolverlo en este momento. Sin embargo, actualizaré el original con dependencias. Si obtiene pistas, las comprobaré con mi código original.
user3810626
1
La sintaxis de CommonJS (require y module.exports) era el formato original para el nodo y el paquete web también lo admite, pero la sintaxis del módulo ES6 (exportar, importar) es la forma más nueva y ahora el nodo y el paquete web lo admiten. Leí que el nodo admite la importación ahora, pero tantos tutoriales muestran que requieren material de nodo puro que probablemente sea mejor usar esa sintaxis para el nodo.
Ted Fitzpatrick
1
Por último, para mí el camino a seguir parece ser la siguiente: github.com/vuejs/vue-jest/issues/134#issuecomment-461755061 Ajuste preestablecido en el jest.config.jsque 'ts-jest/presets/js-with-ts'- todavía tiene algunas otras cuestiones que se resolvió el grande. ..... uh sí, mi problema estaba probando relacionado ... lo normal builds estaban bien
lince
Lynx, interesante. No estoy usando Jest, yo mismo. Ted, interesante. OK, no lo sudaré.
user3810626

Respuestas:

52

Actualización 2020 (Nodo 13.2.0+)

Verifique que tenga instalada la última versión de Node. La --experimental-modulesbandera ya no es necesaria. Simplemente realice una de las siguientes acciones :

  • Agregar "type": "module"al padre más cercano package.json. Con esto, todos .jsy los .mjsarchivos se interpretan como módulos ES. Puede interpretar archivos individuales como CommonJS utilizando la .cjsextensión.

O

  • Explícitamente nombrar archivos con la .mjsextensión. Todos los demás archivos, como .jsse interpretarán como CommonJS, que es el predeterminado si typeno está definido en package.json.
jabacchetta
fuente
Si uso esto, cambie la ruta para incluir las "js" para el archivo requerido, luego cambie el formato de las declaraciones de exportación en el archivo requerido y luego tome todas las declaraciones "requeridas" que cambié de "importar", porque ahora "requerir" es desconocido; esto funcionará, así que aceptaré esta respuesta.
user3810626
2
Esta no es realmente una opción si el problema está en node_modules / right? ¿Alguna idea de cómo solucionarlo en ese caso?
Trent Bing
6

Tuve el mismo problema y lo siguiente lo solucionó (usando el nodo 12.13.1):

  • Cambie la extensión de archivo .js a .mjs
  • Agregue la bandera --experimental-modules al ejecutar su aplicación.
  • Opcional: agregue "type": "module" en su package.json

Más información: https://nodejs.org/api/esm.html

iseenoob
fuente
-1

Tuve este problema en un proyecto incipiente de API Express.

El código del servidor infractor en src/server/server.js:

import express from 'express';
import {initialDonationItems, initialExpenditureItems} from "./DemoData";

const server = express();

server.get('/api/expenditures', (req, res) => {
  res.type('json');
  res.send(initialExpenditureItems);
});

server.get('/api/donations', (req, res) => {
  res.type('json');
  res.send(initialDonationItems);
});

server.listen(4242, () => console.log('Server is running...'));

Aquí estaban mis dependencias:

{
  "name": "contributor-api",
  "version": "0.0.1",
  "description": "A Node backend to provide storage services",
  "scripts": {
    "dev-server": "nodemon --exec babel-node src/server/server.js --ignore dist/",
    "test": "jest tests"
  },
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.9.6",
    "@babel/node": "^7.8.7",
    "babel-loader": "^8.1.0",
    "express": "^4.17.1",
    "mysql2": "^2.1.0",
    "sequelize": "^5.21.7",
    "sequelize-cli": "^5.5.1"
  },
  "devDependencies": {
    "jest": "^25.5.4",
    "nodemon": "^2.0.3"
  }
}

Y aquí estaba el corredor que arrojó el error:

nodemon --exec babel-node src/server/server.js --ignore dist

Esto fue frustrante, ya que tenía un proyecto Express similar que funcionó bien.

La solución fue en primer lugar agregar esta dependencia:

npm install @babel/preset-env

Y luego para conectarlo usando a babel.config.jsen la raíz del proyecto:

module.exports = {
  presets: ['@babel/preset-env'],
};

No entiendo completamente por qué esto funciona, pero lo copié de una fuente autorizada , así que estoy feliz de seguir con eso.

halfer
fuente
Sí, mi problema era que el código tenía un montón de ajustes preestablecidos y nunca pude alcanzar el equilibrio correcto de las cosas que quería versus las cosas que no quería / que rompieron cosas.
user3810626 hace
He estado presionando a través de confusos bloqueos de JS todo el día @ user3810626: sospecho que mi problema es que soy bastante nuevo en el lenguaje y el ecosistema, y ​​necesito dejar de lado algo de aprendizaje por ahora para que las cosas funcionen. Cómo llegar ...:-)
halfer hace
1
¡Buena suerte! ¡Hay una jungla ahí fuera! (Quiero decir, literalmente, el ecosistema JS es una jungla ...)
user3810626 hace
-2
  1. Tuve el mismo problema cuando comencé a usar Babel ... Pero más tarde, tuve una solución ... Ya no he tenido el problema hasta ahora ... Actualmente, Nodo v12.14.1, "@ babel / node" : "^ 7.8.4", utilizo babel-node y nodemon para ejecutar (el nodo también está bien ...)
  2. package.json: "start": "nodemon --exec babel-node server.js" debug ":" babel-node debug server.js "!! nota: server.js es mi archivo de entrada, puede usar el suyo.
  3. launch.json Cuando depure , también necesita configurar su archivo launch.json "runtimeExecutable": "$ {workspaceRoot} /node_modules/.bin/babel-node" !! nota: más runtimeExecutable en la configuración.
  4. Por supuesto, con babel-node, normalmente también necesita y edita otro archivo, como babel.config.js / .babelrc
MrLetmein
fuente
-2

Mi solución fue incluir la ruta del nodo babel mientras ejecuta nodemon de la siguiente manera:

nodemon node_modules/.bin/babel-node index.js

puede agregar en su script package.json como:

debug: nodemon node_modules/.bin/babel-node index.js

NOTA: Mi archivo de entrada es index.js, reemplácelo con su archivo de entrada (muchos tienen app.js / server.js).

ishab acharya
fuente