Node.js - SyntaxError: importation de jeton inattendue

444

Je ne comprends pas ce qui ne va pas. Node v5.6.0 NPM v3.10.6

Le code:

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

L'erreur:

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
SofDroid
la source
4
Utilisez un transpilateur comme Babel pour utiliser l'importation dans Nodejs car il n'est pas pris en charge nativement dans nodejs.Il existe la meilleure alternative d'importation est nécessaire, alors allez-y.
BHUVNESH KUMAR

Réponses:

485

Mise à jour 3: depuis le nœud 13 , vous pouvez utiliser l'extension .mjs ou définir "type": "module" dans votre package.json. Vous n'avez pas besoin d'utiliser le --experimental-modulesdrapeau.

Mise à jour 2: depuis le nœud 12 , vous pouvez utiliser l' .mjsextension ou la définir "type": "module"dans votre package.json. Et vous devez exécuter le nœud avec le --experimental-modulesdrapeau.

Mise à jour: dans le nœud 9 , il est activé derrière un indicateur et utilise l' .mjsextension.

node --experimental-modules my-app.mjs

Bien qu'il importfasse en effet partie d'ES6, il n'est malheureusement pas encore pris en charge par défaut dans NodeJS et n'a que très récemment pris en charge les navigateurs.

Voir le tableau de compatibilité du navigateur sur MDN et ce problème de nœud .

Extrait de la mise à jour de James M Snell sur les modules ES6 dans Node.js (février 2017):

Les travaux sont en cours mais cela va prendre un certain temps - Nous envisageons actuellement environ un an au moins.

Jusqu'à ce que le support apparaisse nativement, vous devrez continuer à utiliser des requireinstructions classiques :

const express = require("express");

Si vous voulez vraiment utiliser les nouvelles fonctionnalités ES6 / 7 dans NodeJS, vous pouvez le compiler en utilisant Babel. Voici un exemple de serveur .

Scimonster
la source
2
Quelqu'un sait-il si le nœud 10 sera livré avec un support activé par défaut? (prévue pour le mois prochain)
Hartmut
2
@Scimonster ...... node --experimental-modules my-app.mjs (node: 12176) ExperimentalWarning: Le chargeur de module ESM est expérimental. {Erreur: impossible de trouver le module /C:/Users/WittyParrot/Documents/card-test-project/src/my-app.mjs lors de la recherche (interne / modules / esm / DefaultResolve.js: 23: 12) test-project / src / my-app.mjs lors de la recherche (internal / modules / esm / DefaultResolve.js: 23: 12) .... lancer un avertissement n'a pas pu trouver my-app.js .... veuillez suggérer .... i version 9.11.1 du nœud installé
Leo

52
frustrant parce que la majorité des tutoriels parlent de l'utilisation de l'importation, mais il n'y a presque pas de support pour cela. (Je veux revenir 2 heures de ma vie lol)
kiwicomb123

9
@ChaimEliyah: a le même problème dans le noeud v11.0.0
whoami


60

Malheureusement, Node.js ne prend pas encore en charge ES6 import.

Pour accomplir ce que vous essayez de faire (importer le module Express), ce code devrait suffire

var express = require("express");

Assurez-vous également que Express est installé en exécutant

$ npm install express

Consultez la documentation Node.js pour plus d'informations sur l'apprentissage de Node.js.


8
importn'est pas nécessairement une fonctionnalité de TypeScript. TypeScript est ES6 avec des typages. Donc, des choses comme l'importation sont natives ES6.
borislemke

@borislemke C'est vrai, j'ai mal interprété le PO. :) Je vais le changer.
baranskistad

salut, j'ai installé express mais dans le script du fichier package.json que devons-nous écrire? Si j'écris des "scripts": {"start": "node index.js"} alors il devrait afficher la même erreur. Aidez-moi, s'il vous plaît.
Ravi Shah
node index.jstravaille pour moi, mais quand je cours, node dist/main.jsje reçois aussi Unexpected token import.
TheFox
@TheFox vous avez probablement une importation dans ce fichier. Ce index.jsn'est pas parce que vous dist/main.jspassez que votre volonté passera aussi.
baranskistad le
34

Comme mentionné dans d'autres réponses, le nœud JS ne prend actuellement pas en charge les importations ES6.

(À partir de maintenant, lisez EDIT 2)

Activer les importations ES6 dans le nœud js fournit une solution à ce problème. J'ai essayé cela et cela a fonctionné pour moi.

Exécutez la commande:

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

Vous devez maintenant créer un nouveau fichier (config.js) et y ajouter le code suivant.

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

Vous pouvez maintenant écrire des instructions d'importation sans obtenir d'erreurs.

J'espère que cela t'aides.

ÉDITER:

Vous devez exécuter le nouveau fichier que vous avez créé avec le code ci-dessus. Dans mon cas, ça l'était config.js. Je dois donc courir:

    node config.js

EDIT 2:

En expérimentant, j'ai trouvé une solution simple à ce problème.

Créez un .babelrcfichier à la racine de votre projet.

Ajoutez les éléments suivants (et tous les autres préréglages babel dont vous avez besoin, peuvent être ajoutés dans ce fichier):

    {
        "presets": ["env"]
    }

Installer à l' babel-preset-envaide de la commande npm install babel-preset-env --save, puis installer à l' babel-cliaide de la commandenpm install babel-cli -g --save

Maintenant, allez dans le dossier où existe votre serveur ou fichier d'index et exécutez en utilisant: babel-node fileName.js

Ou vous pouvez exécuter en utilisant npm starten ajoutant le code suivant à votre package.jsonfichier:

    "scripts": {
        "start": "babel-node src/index.js"
    }
Neerali Acharya
la source
Comment dois-je procéder avec l'électron? J'ai essayé comme ça: "start": "babel-node electron .", mais pas de chance
tpbafk
2
@tpbafk Je n'ai pas travaillé sur l'électron. Mais j'ai trouvé quelque chose de similaire à votre problème javascript - Comment définir le démarrage de npm pour l'application électronique avec 'babel-node --presets es2015, stage-3' . J'espère que ça aide
Neerali Acharya
33

Erreur: SyntaxError: importation de jeton inattendue ou SyntaxError: exportation de jeton inattendue


Solution: changez toutes vos importations comme exemple

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

Et aussi changer votre export default = foo;àmodule.exports = foo;

supritshah1289
la source
1
Je souhaite que vous auriez expliqué un peu plus la partie export par défaut. J'ai des problèmes avec cette partie. L'importation fonctionne très bien avec votre réponse.
JoeGalind
Il y a une réponse avant ma réponse qui a une explication. Mais pour plus de précision, Node ne prend pas en charge la syntaxe ES6. Lorsque vous dites Importer ... vous utilisez la syntaxe ES6
ES6 supritshah1289
22

Je suis choqué esmn'a pas été mentionné. Ce petit mais puissant package vous permet d'utiliser soit importou require.

Installez esm dans votre projet

$ npm install --save esm

Mettez à jour votre script de démarrage de noeud pour utiliser esm

node -r esm app.js

esmfonctionne juste. J'ai perdu une tonne de temps avec .mjset --experimental-modulesseulement pour découvrir qu'un .mjsfichier ne peut pas importer un fichier qui utilise requireou module.exports. C'était un énorme problème, alors qu'il esmvous permet de mélanger et assortir et il suffit de le comprendre ... ça esmfonctionne.

thedanotto
la source
17

Dans le cas où vous ne pouvez toujours pas utiliser "importer", voici comment je l'ai géré: il suffit de le traduire en un besoin convivial pour les nœuds. Exemple:

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

Est le même que:

const parse = require('node-html-parser').parse;
Alberto
la source
4
pas vrai si vous utilisez (comme c'est probablement le cas) le exportmot
Daniel Thompson
@DanielThompson Désolé si cela peut être mal compris, je donne juste une solution de contournement pour ce cas, si vous travaillez sans le exportmot - clé, merci de toute façon pour votre note utile!
Alberto
Travailler pour moi. Merci
Ali Azhar
11

babel 7 proposition pouvez-vous ajouter des dépendances dev

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

et ajoutez un .babelrc à la racine

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

et ajouter au fichier .js

require("@babel/register")

ou si vous l'exécutez dans le cli, vous pouvez utiliser le hook requis comme -r @ babel / register, ex.

$node -r @babel/register executeMyFileWithESModules.js
Jason Ashley
la source
1
Installer @ babel / preset-env et l'ajouter à .babelrc a fait l'affaire. Pas besoin de plugin @ babel / register dans mon cas.
Marcos R
8

si vous pouvez utiliser 'babel', essayez d'ajouter des scripts de construction dans package.json (- presets = es2015) comme ci-dessous. il permet de précompiler le code d'importation vers es2015

"build": "babel server --out-dir build --presets=es2015 && webpack"
ASTOMUSIQUE
la source
mais est-ce que mon appel pour d' npm startabord faire la "build", ou d'abord faire le "start"? (Le départ est actuellement défini:"nodemon src/app.js --exec \"npm run lint && node\"",
pashute
si j'exécute cette cmd, cela montre que le serveur n'existe pas
kumaresan_sd
6

À partir de Node.js v12 (et c'est probablement assez stable maintenant, mais toujours marqué "expérimental"), vous avez quelques options pour utiliser ESM ( E CMA S cript M odules) dans Node.js (pour les fichiers, il y a un troisième méthode pour évaluer les chaînes), voici ce que dit la documentation :

L' --experimental-modulesindicateur peut être utilisé pour activer la prise en charge des modules ECMAScript (modules ES).

Une fois activé, Node.js traitera les éléments suivants comme des modules ES lorsqu'ils sont passés à nodel'entrée initiale ou lorsqu'ils sont référencés par des importinstructions dans le code du module ES:

  • Fichiers se terminant par .mjs.

  • Fichiers se terminant par .jsou fichiers sans extension, lorsque le package.jsonfichier parent le plus proche contient un champ de niveau supérieur "type"avec une valeur de "module".

  • Les chaînes sont passées en argument à --evalou --print, ou dirigées vers nodevia STDIN, avec l'indicateur --input-type=module.

Node.js traitera comme CommonJS toutes les autres formes d'entrée, telles que les .jsfichiers où le package.jsonfichier parent le plus proche ne contient aucun "type" champ de niveau supérieur , ou une entrée de chaîne sans l'indicateur --input-type. Ce comportement vise à préserver la compatibilité descendante. Cependant, maintenant que Node.js prend en charge les modules CommonJS et ES, il est préférable d'être explicite dans la mesure du possible. Node.js traitera les éléments suivants comme CommonJS lorsqu'il est transmis à nodel'entrée initiale ou lorsqu'il est référencé par des importinstructions dans le code du module ES:

  • Fichiers se terminant par .cjs.

  • Fichiers se terminant par .jsou fichiers sans extension, lorsque le package.jsonfichier parent le plus proche contient un champ de niveau supérieur "type"avec une valeur de "commonjs".

  • Les chaînes sont passées en argument à --evalou --print, ou dirigées vers nodevia STDIN, avec l'indicateur --input-type=commonjs.

TJ Crowder
la source
3

Quand j'ai commencé avec express, j'ai toujours voulu une solution pour utiliser l'importation à la place

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

Beaucoup de temps passent par cette ligne: - Unfortunately, Node.js doesn't support ES6's import yet.

Maintenant, pour aider les autres, je crée de nouvelles solutions ici

1) esm : -

Le chargeur de module ECMAScript brillamment simple, sans babel, sans bundle. faisons en sorte que ça marche

  yarn add esm / npm install esm

créez start.js ou utilisez votre espace de noms

 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

Changement de votre package.josnchemin d'accèsstart.js

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

2) Babel js : -

Cela peut être divisé en 2 parties

a) Solution 1 grâce à timonweb.com

b) Solution 2

utiliser Babel 6 (ancienne version de babel-preset-stage-3 ^ 6.0 ) créer un .babelrcfichier dans votre dossier racine

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

Installer babel-preset-stage-3

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

Changement dans 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"
},

Démarrez votre serveur

yarn start / npm start

Oooh non nous créons un nouveau problème

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

Cette erreur ne survient que lorsque vous utilisez async / wait dans votre code. Utilisez ensuite polyfill qui inclut un runtime de régénérateur personnalisé et core-js. ajouter par-dessusindex.js

import "babel-polyfill"

Cela vous permet d'utiliser async / wait

utiliser Babel 7

Besoin de mettre à jour chaque élément de votre projet, commençons par babel 7 .babelrc

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

Quelques changements dans 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"
....
}

et utiliser import "@babel/polyfill"sur le point de départ

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

Pensez-vous pourquoi start:dev

Sérieusement. C'est une bonne question si vous êtes nouveau. Chaque changement que vous êtes sanglier avec le serveur de démarrage à chaque fois, puis utilisez yarn start:devcomme serveur de développement chaque changement de serveur de redémarrage automatiquement pour plus d'informations sur nodemon

Ashok
la source
2

Dans mon cas, il s'occupait du .babelrcfichier et il devrait contenir quelque chose comme ceci:

{
  "presets": ["es2015-node5", "stage-3"],
  "plugins": []
}
Ghita Tomoiaga
la source