Node.js - SyntaxError: importazione token imprevista


443

Non capisco cosa c'è che non va. Nodo v5.6.0 NPM v3.10.6

Il codice:

function (exports, require, module, __filename, __dirname) {
    import express from 'express'
};

L'errore:

SyntaxError: Unexpected token import
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:387:25)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:140:18)
    at node.js:1001:3

4
Usa il transpiler come Babel per usare l'importazione in Nodejs in quanto non è supportato nativamente in nodejs. C'è la migliore alternativa all'importazione, quindi procedi con quello.
BHUVNESH KUMAR,

Risposte:


484

Aggiornamento 3: Dal Nodo 13 , è possibile utilizzare l'estensione .mjs oppure impostare "type": "module" in package.json. Non è necessario utilizzare la --experimental-modulesbandiera.

Aggiornamento 2: dal Nodo 12 , è possibile utilizzare l' .mjsestensione o impostarla "type": "module"in package.json. Ed è necessario eseguire il nodo con la --experimental-modulesbandiera.

Aggiornamento: nel nodo 9 , è abilitato dietro un flag e utilizza l' .mjsestensione.

node --experimental-modules my-app.mjs

Sebbene importfaccia effettivamente parte di ES6, sfortunatamente non è ancora supportato in NodeJS per impostazione predefinita e solo di recente ha ottenuto il supporto nei browser.

Vedere la tabella di compatibilità del browser su MDN e questo problema relativo al nodo .

Dall'aggiornamento di James M Snell sui moduli ES6 in Node.js (febbraio 2017):

I lavori sono in corso ma ci vorrà del tempo - Al momento stiamo guardando almeno un anno.

Fino a quando il supporto non viene visualizzato in modo nativo, dovrai continuare a utilizzare le requireistruzioni classiche :

const express = require("express");

Se vuoi davvero usare le nuove funzionalità ES6 / 7 in NodeJS, puoi compilarlo usando Babel. Ecco un esempio di server .


2
qualcuno sa se il nodo 10 verrà fornito con il supporto abilitato per impostazione predefinita? (il debutto il prossimo mese)
Hartmut,

2
@Scimonster ...... node --experimental-modules my-app.mjs (nodo: 12176) ExperimentalWarning: il caricatore del modulo ESM è sperimentale. {Errore: impossibile trovare il modulo /C:/Users/WittyParrot/Documents/card-test-project/src/my-app.mjs alla ricerca (internal / modules / esm / DefaultResolve.js: 23: 12) test-project / src / my-app.mjs alla ricerca (internal / modules / esm / DefaultResolve.js: 23: 12) .... lanciando un avviso non è stato possibile trovare my-app.js .... per favore suggerisci .... i nodo installato versione 9.11.1
Leo

52
frustrante perché la maggior parte dei tutorial là fuori parla di usare l'importazione, ma non c'è quasi alcun supporto per questo. (Voglio 2 ore della mia vita indietro lol)
kiwicomb123

9
@ChaimEliyah: ha avuto lo stesso problema nel nodo v11.0.0
whoami il

5
Richiede ancora un flag in v12 nodejs.org/api/esm.html#esm_ecmascript_modules
ABabin

60

Sfortunatamente, Node.js non supporta importancora ES6 .

Per realizzare ciò che stai tentando di fare (importa il modulo Express), questo codice dovrebbe essere sufficiente

var express = require("express");

Inoltre, assicurati di avere Express installato eseguendo

$ npm install express

Consulta la documentazione di Node.js per ulteriori informazioni sull'apprendimento di Node.js.


8
importnon è necessariamente una caratteristica di TypeScript. TypeScript è ES6 con le digitazioni. Quindi cose come l'importazione sono native di ES6.
Borislemke,

@borislemke Vero, ho interpretato l'OP un po 'male. :) Lo cambierò.
Baranskistad,

ciao, ho installato express ma nello script del file package.json cosa dovremmo scrivere? Se scrivo "script": {"start": "node index.js"}, dovrebbe visualizzare lo stesso errore. mi aiuti per favore.
Ravi Shah,

node index.jsfunziona per me, ma quando corro node dist/main.jsanche io Unexpected token import.
TheFox

@TheFox probabilmente hai un'importazione in quel file. Solo perché stai index.jspassando non significa che dist/main.jspasserà anche la tua.
baranskistad,

34

Come menzionato in altre risposte, il nodo JS attualmente non supporta le importazioni ES6.

(A partire da ora, leggi EDIT 2)

Abilitare le importazioni ES6 nel nodo js offre una soluzione a questo problema. Ho provato questo e ha funzionato per me.

Esegui il comando:

    npm install babel-register babel-preset-env --save-dev

Ora devi creare un nuovo file (config.js) e aggiungere il seguente codice ad esso.

    require('babel-register')({
        presets: [ 'env' ]
    })
    // Import the rest of our application.
    module.exports = require('./your_server_file.js')

Ora puoi scrivere dichiarazioni di importazione senza ottenere errori.

Spero che sia di aiuto.

MODIFICARE:

Devi eseguire il nuovo file che hai creato con il codice sopra. Nel mio caso lo era config.js. Quindi devo correre:

    node config.js

MODIFICA 2:

Durante la sperimentazione, ho trovato una soluzione semplice a questo problema.

Crea il .babelrcfile nella radice del tuo progetto.

Aggiungi il seguente (e qualsiasi altro preset babel di cui hai bisogno, può essere aggiunto in questo file):

    {
        "presets": ["env"]
    }

Installa babel-preset-envusando il comando npm install babel-preset-env --save, quindi installa babel-cliusando il comandonpm install babel-cli -g --save

Ora, vai alla cartella in cui esiste il tuo server o file indice ed esegui usando: babel-node fileName.js

Oppure puoi eseguire usando l' npm startaggiunta del seguente codice al tuo package.jsonfile:

    "scripts": {
        "start": "babel-node src/index.js"
    }

Come posso farlo con l'elettrone? Ho provato in questo modo: "start": "babel-node electron .", ma senza fortuna
tpbafk,

2
@tpbafk Non ho lavorato sull'elettrone. Ma ho trovato qualcosa di simile al tuo problema javascript - Come impostare npm start per l'app di elettroni con 'babel-node --presets es2015, stage-3' . Spero che aiuti
Neerali Acharya

33

Errore: SyntaxError: importazione token imprevista o SyntaxError: esportazione token imprevista


Soluzione: modificare tutte le importazioni come esempio

const express               = require('express');
const webpack               = require('webpack');
const path                  = require('path');
const config                = require('../webpack.config.dev');
const open                  = require('open');

E anche cambiare la vostra export default = foo;amodule.exports = foo;


1
Vorrei che avessi spiegato un po 'di più la parte predefinita di esportazione. Sto avendo problemi con quella parte. L'importazione funziona alla grande con la tua risposta.
Joe Galind

C'è una risposta prima della mia risposta che ha una spiegazione. Ma per chiarimenti Nodo non supporta la sintassi ES6. Quando dici Import ... stai usando la sintassi ES6
supritshah1289 del

22

Sono scioccato esmnon è stato menzionato. Questo pacchetto piccolo ma potente ti consente di utilizzare entrambiimport o require.

Installa esm nel tuo progetto

$ npm install --save esm

Aggiorna il tuo Node Start Script per usare esm

node -r esm app.js

esmfunziona e basta. Ho perso un sacco di tempo con .mjse --experimental-modulessolo per scoprire un .mjsfile non è possibile importare un file che utilizza requireo module.exports. Questo è stato un grosso problema, mentre esmti permette di mescolare e abbinare e lo capisce ... esmfunziona e basta.


17

Nel caso in cui non sia ancora possibile utilizzare "import", ecco come l'ho gestito: è sufficiente tradurlo in un nodo necessario. Esempio:

import { parse } from 'node-html-parser';

Equivale a:

const parse = require('node-html-parser').parse;

4
non è vero se stai utilizzando (come probabilmente è il caso) la exportparola chiave
Daniel Thompson il

@DanielThompson Mi dispiace se questo può essere un fraintendimento, sto solo dando una soluzione per questo caso, se lavori senza la exportparola chiave, comunque grazie per la tua utile nota!
Alberto,

Lavora per me. Grazie
Ali Azhar il

11

proposta babel 7 puoi aggiungere dipendenze dev

npm i -D @babel/core @babel/preset-env @babel/register

e aggiungi un .babelrc nella radice

{
"presets": [
  [
    "@babel/preset-env",
    {
      "targets": {
        "node": "current"
     }
    }
  ]
 ]
}

e aggiungi al file .js

require("@babel/register")

oppure se lo esegui nel cli, puoi usare l'hook richiesto come -r @ babel / register, es.

$node -r @babel/register executeMyFileWithESModules.js

1
Installare @ babel / preset-env e aggiungerlo a .babelrc ha reso il trucco. Nel mio caso non è necessario il plug-in @ babel / register.
Marcos R,

8

se puoi usare 'babel', prova ad aggiungere gli script di build in package.json (- presets = es2015) come di seguito. fa precompilare il codice di importazione in es2015

"build": "babel server --out-dir build --presets=es2015 && webpack"

ma la mia chiamata a npm startfare prima "build" o prima "start"? (L'inizio è attualmente definito:"nodemon src/app.js --exec \"npm run lint && node\"",
pashute

se
eseguo

6

A partire da Node.js v12 (e questo è probabilmente abbastanza stabile ora, ma ancora contrassegnato come "sperimentale"), hai un paio di opzioni per usare ESM ( E CMA S cript M odules) in Node.js (per i file, c'è un terzo modo per valutare le stringhe), ecco cosa dice la documentazione :

Il --experimental-modules flag può essere utilizzato per abilitare il supporto per i moduli ECMAScript (moduli ES).

Una volta abilitato, Node.js tratterà quanto segue come moduli ES quando verrà passato nodecome input iniziale o quando sarà indicato da importistruzioni nel codice del modulo ES:

  • File che terminano con .mjs.

  • File che terminano con .jso senza estensione, quando il package.jsonfile principale più vicino contiene un campo di livello superiore "type"con un valore di "module".

  • Le stringhe sono passate come argomento a --evalo --print, o reindirizzate a nodevia STDIN, con la bandiera --input-type=module.

Node.js tratterà come CommonJS tutte le altre forme di input, come i .jsfile in cui il package.jsonfile padre più vicino non contiene "type" campi di livello superiore o input di stringa senza il flag --input-type. Questo comportamento serve a preservare la compatibilità con le versioni precedenti. Tuttavia, ora che Node.js supporta sia i moduli CommonJS che ES, è meglio essere espliciti quando possibile. Node.js tratterà quanto segue come CommonJS quando viene passato nodecome input iniziale o quando viene fatto riferimento da importistruzioni nel codice del modulo ES:

  • File che terminano con .cjs.

  • File che terminano con .jso senza estensione, quando il package.jsonfile principale più vicino contiene un campo di livello superiore "type"con un valore di "commonjs".

  • Le stringhe sono passate come argomento a --evalo --print, o reindirizzate a nodevia STDIN, con la bandiera --input-type=commonjs.


3

Quando ho iniziato con express ho sempre desiderato una soluzione da utilizzare per l'importazione

const express = require("express");
// to 
import express from "express"

Molte volte passano attraverso questa linea: - Unfortunately, Node.js doesn't support ES6's import yet.

Ora, per aiutare gli altri, creo qui due nuove soluzioni

1) esm : -

Il caricatore di moduli ECMAScript straordinariamente semplice, senza babele e senza fasci. facciamolo funzionare

  yarn add esm / npm install esm

crea start.js o usa il tuo spazio dei nomi

 require = require("esm")(module/*, options*/)
 // Import the rest of our application.
 module.exports = require('./src/server.js')
 // where server.js is express server start file

Modifica nel package.josnpercorso del passaggio distart.js

  "scripts": {
    "start": "node start.js",
    "start:dev": "nodemon start.js",
  },
  "dependencies": {
+    "esm": "^3.2.25",
  },
  "devDependencies": {
+   "nodemon": "^1.19.2"
  }

2) Babel js : -

Questo può essere diviso in 2 parti

a) Soluzione 1 grazie a timonweb.com

b) Soluzione 2

usa Babel 6 (versione precedente di babel-preset-stage-3 ^ 6.0 ) per creare il .babelrcfile nella cartella principale

{
    "presets": ["env", "stage-3"]
}

Installa babel-preset-stage-3

yarn add babel-cli babel-polyfill babel-preset-env bable-preset-stage-3 nodemon --dev

Modifica in package.json

"scripts": {
+   "start:dev": "nodemon --exec babel-node -- ./src/index.js",
+   "start": "npm run build && node ./build/index.js",
+   "build": "npm run clean && babel src -d build -s --source-maps --copy-files",
+   "clean": "rm -rf build && mkdir build"
},
"devDependencies": {
+    "babel-cli": "^6.26.0",
+    "babel-polyfill": "^6.26.0",
+    "babel-preset-env": "^1.7.0",
+    "babel-preset-stage-3": "^6.24.1",
+    "nodemon": "^1.19.4"
},

Avvia il tuo server

yarn start / npm start

Oooh no, creiamo un nuovo problema

regeneratorRuntime.mark(function _callee(email, password) {
^
ReferenceError: regeneratorRuntime is not defined

Questo errore si verifica solo quando usi async / wait nel tuo codice. Quindi utilizzare polyfill che include un runtime di rigeneratore personalizzato e core-js. aggiungi sopraindex.js

import "babel-polyfill"

Ciò ti consente di utilizzare asincrono / wait

usa Babele 7

Hai bisogno di aggiornare ogni cosa nel tuo progetto, inizia con babel 7 .babelrc

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

Alcuni cambiamenti in package.json

"scripts": {
+  "start:dev": "nodemon --exec babel-node -- ./src/index.js",
+  "start": "npm run build && node ./build/index.js",
+  "build": "npm run clean && babel src -d build -s --source-maps --copy-files",
+  "clean": "rm -rf build && mkdir build",
    ....
}
"devDependencies": {
+   "@babel/cli": "^7.0.0",
+   "@babel/core": "^7.6.4",
+   "@babel/node": "^7.0.0",
+   "@babel/polyfill": "^7.0.0",
+   "@babel/preset-env": "^7.0.0",
+   "nodemon": "^1.19.4"
....
}

e utilizzare import "@babel/polyfill"sul punto iniziale

import "@babel/polyfill"
import express from 'express'
const app = express()

//GET request
app.get('/', async (req, res) {
  // await operation
  res.send('hello world')
})
app.listen(4000, () => console.log('🚀 Server listening on port 400!'))

Stai pensando al perché start:dev

Sul serio. È una buona domanda se sei nuovo. Ogni modifica che verrai con il server di avvio ogni volta, quindi utilizza yarn start:devcome server di sviluppo ogni modifica riavvia il server automaticamente per ulteriori informazioni su nodemon


2

Nel mio caso si stava occupando del .babelrcfile e dovrebbe contenere qualcosa del genere:

{
  "presets": ["es2015-node5", "stage-3"],
  "plugins": []
}
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.