Node.js - SyntaxError: Impor token yang tidak terduga

443

Saya tidak mengerti apa yang salah. Node v5.6.0 NPM v3.10.6

Kode:

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

Kesalahan:

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
sumber
4
Gunakan transpiler seperti Babel untuk menggunakan impor di Nodejs karena tidak didukung secara native di nodejs.Ada alternatif impor terbaik yang diperlukan jadi lanjutkan dengan itu.
BHUVNESH KUMAR

Jawaban:

484

Pembaruan 3: Sejak Node 13 , Anda dapat menggunakan ekstensi .mjs, atau mengatur "type": "module" di package.json Anda. Anda tidak perlu menggunakan --experimental-modulesbendera.

Pembaruan 2: Sejak Node 12 , Anda dapat menggunakan .mjsekstensi, atau mengatur "type": "module"package.json Anda. Dan Anda perlu menjalankan simpul dengan --experimental-modulesbendera.

Pembaruan: Di Node 9 , diaktifkan di belakang bendera, dan menggunakan .mjsekstensi.

node --experimental-modules my-app.mjs

Walaupun importmemang merupakan bagian dari ES6, sayangnya ini belum didukung di NodeJS secara default, dan baru-baru ini mendapatkan dukungan di browser.

Lihat tabel compat browser di MDN dan masalah Node ini .

Dari Pembaruan James M Snell tentang Modul ES6 di Node.js (Februari 2017):

Pekerjaan sedang berlangsung tetapi itu akan memakan waktu - Kami saat ini setidaknya melihat sekitar satu tahun.

Sampai dukungan muncul secara asli, Anda harus terus menggunakan requirepernyataan klasik :

const express = require("express");

Jika Anda benar-benar ingin menggunakan fitur ES6 / 7 baru di NodeJS, Anda dapat mengompilasinya menggunakan Babel. Inilah contoh server .

Scimonster
sumber
2
apakah ada yang tahu jika node 10 akan dikirimkan dengan dukungan yang diaktifkan secara default? (dijadwalkan untuk debut bulan depan)
Hartmut
2
@Scimonster ...... node --experimental-modules my-app.mjs (node: 12176) ExperimentalWarning: Loader modul ESM bersifat eksperimental. {Error: Tidak dapat menemukan module /C:/Users/WittyParrot/Documents/card-test-project/src/my-app.mjs saat mencari (internal / modules / esm / DefaultResolve.js: 23: 12) test-project / src / my-app.mjs pada pencarian (internal / modules / esm / DefaultResolve.js: 23: 12) .... melemparkan peringatan tidak dapat menemukan my-app.js .... mohon sarankan .... i menginstal node versi 9.11.1
Leo

52
membuat frustrasi karena sebagian besar tutorial di luar sana berbicara tentang menggunakan impor, tetapi hampir tidak ada dukungan untuk itu. (Saya ingin 2 jam hidup saya kembali lol)
kiwicomb123

9
@ChaimEliyah: mendapat masalah yang sama di simpul v11.0.0
whoami

5
Masih membutuhkan sebuah flag di v12 nodejs.org/api/esm.html#esm_ecmascript_modules
ABabin

60

Sayangnya, Node.js belum mendukung ES6 import.

Untuk mencapai apa yang Anda coba lakukan (mengimpor modul Express), kode ini sudah cukup

var express = require("express");

Juga, pastikan Anda telah menginstal Express dengan menjalankan

$ npm install express

Lihat Node.js Documents untuk informasi lebih lanjut tentang mempelajari Node.js.


8
importbelum tentu merupakan fitur dari TypeScript. TypeScript adalah ES6 dengan mengetik. Jadi barang-barang seperti impor adalah ES6 asli.
borislemke

@borislemke Benar, saya menafsirkan OP sedikit salah. :) Saya akan mengubahnya.
baranskistad

hai, saya menginstal express tetapi dalam skrip file package.json apa yang harus kita tulis? Jika saya menulis "skrip": {"start": "node index.js"} maka itu akan menampilkan kesalahan yang sama. tolong bantu aku.
Ravi Shah
node index.jsbekerja untuk saya, tetapi ketika saya menjalankan node dist/main.jssaya juga mendapatkan Unexpected token import.
TheFox
@TheFox Anda mungkin memiliki impor di file itu. Hanya karena Anda index.jslulus tidak berarti Anda dist/main.jsakan lulus juga.
baranskistad
34

Seperti disebutkan dalam jawaban lain Node JS saat ini tidak mendukung impor ES6.

(Sampai sekarang, baca EDIT 2)

Aktifkan impor ES6 di simpul js memberikan solusi untuk masalah ini. Saya sudah mencoba ini dan itu berhasil untuk saya.

Jalankan perintah:

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

Sekarang Anda perlu membuat file baru (config.js) dan menambahkan kode berikut ke dalamnya.

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

Sekarang Anda dapat menulis pernyataan impor tanpa mendapatkan kesalahan.

Semoga ini membantu.

EDIT:

Anda perlu menjalankan file baru yang Anda buat dengan kode di atas. Dalam kasus saya itu config.js. Jadi saya harus lari:

    node config.js

EDIT 2:

Saat bereksperimen, saya menemukan satu solusi mudah untuk masalah ini.

Membuat .babelrc file di root proyek Anda.

Tambahkan berikut ini (dan semua preset babel lainnya yang Anda butuhkan, dapat ditambahkan dalam file ini):

    {
        "presets": ["env"]
    }

Instal babel-preset-envmenggunakan perintah npm install babel-preset-env --save, lalu instalbabel-cli menggunakan perintahnpm install babel-cli -g --save

Sekarang, buka folder tempat server atau file indeks Anda ada dan jalankan menggunakan: babel-node fileName.js

Atau Anda dapat menjalankan menggunakan npm startdengan menambahkan kode berikut ke package.jsonfile Anda :

    "scripts": {
        "start": "babel-node src/index.js"
    }
Neerali Acharya
sumber
Bagaimana saya melakukan ini dengan elektron? Saya mencoba seperti ini: "start": "babel-node electron .", tetapi tidak berhasil
tpbafk
2
@ tpbafk saya belum bekerja pada elektron. Tapi saya menemukan sesuatu yang mirip dengan masalah Anda javascript - Cara mengatur npm mulai untuk aplikasi elektron dengan 'babel-node --presets es2015, stage-3' . Semoga ini bisa membantu
Neerali Acharya
33

Kesalahan: SyntaxError: Impor token yang tidak terduga atau SyntaxError: Ekspor token yang tidak terduga


Solusi: Ubah semua impor Anda sebagai contoh

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

Dan juga ubah export default = foo;kemodule.exports = foo;

supritshah1289
sumber
1
Saya berharap Anda akan menjelaskan sedikit bagian standar ekspor. Saya mengalami masalah dengan bagian itu. Impor berfungsi baik dengan jawaban Anda.
JoeGalind
Ada jawaban sebelum jawaban saya yang memiliki penjelasan. Tetapi untuk klarifikasi Node tidak mendukung sintaks ES6. Ketika Anda mengatakan Impor ... Anda menggunakan sintaks
ES6
22

Saya terkejut esmbelum disebutkan. Paket kecil ini, tetapi perkasa memungkinkan Anda untuk menggunakan salah satu importatau require.

Instal ESM di proyek Anda

$ npm install --save esm

Perbarui Script Mulai Node Anda untuk menggunakan ESM

node -r esm app.js

esmhanya bekerja. Saya menyia-nyiakan waktu TON dengan .mjsdan --experimental-moduleshanya untuk mengetahui .mjsfile tidak dapat mengimpor file yang menggunakan requireatau module.exports. Ini adalah masalah besar, sedangkan esmmemungkinkan Anda untuk mencampur dan mencocokkan dan itu hanya mencari tahu ... esmhanya berfungsi.

mantra
sumber
17

Jika Anda masih tidak dapat menggunakan "impor" di sini adalah bagaimana saya menanganinya: Hanya menerjemahkannya ke simpul yang diperlukan. Contoh:

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

Sama dengan:

const parse = require('node-html-parser').parse;
Alberto
sumber
4
tidak benar jika Anda (seperti yang mungkin terjadi) menggunakan exportkata kunci
Daniel Thompson
@DanielThompson Maaf jika ini bisa salah paham, saya hanya memberikan solusi untuk kasus ini, jika Anda bekerja tanpa exportkata kunci, lagipula terima kasih atas bantuan Anda!
Alberto
Bekerja untukku. Terima kasih
Ali Azhar
11

Babel 7 proposal dapat Anda tambahkan dependensi dev

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

dan tambahkan .babelrc di root

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

dan tambahkan ke file .js

require("@babel/register")

atau jika Anda menjalankannya di cli, Anda dapat menggunakan hook yang memerlukan sebagai -r @ babel / register, mis.

$node -r @babel/register executeMyFileWithESModules.js
Jason Ashley
sumber
1
Menginstal @ babel / preset-env dan menambahkannya ke .babelrc membuat trik. Tidak perlu untuk plugin @ babel / register dalam kasus saya.
Marcos R
8

jika Anda dapat menggunakan 'babel', cobalah untuk menambahkan skrip build di package.json (- preset = es2015) seperti di bawah ini. itu membuat mengkompilasi kode impor ke es2015

"build": "babel server --out-dir build --presets=es2015 && webpack"
ASTOMUSIK
sumber
tetapi apakah panggilan saya untuk npm startpertama kali melakukan "build", atau yang pertama melakukan "start"? (Awal saat ini didefinisikan:"nodemon src/app.js --exec \"npm run lint && node\"",
pashute
jika saya menjalankan cmd ini, ini menunjukkan server tidak ada kesalahan
kumaresan_sd
6

Pada Node.js v12 (dan ini mungkin cukup stabil sekarang, tetapi masih ditandai "eksperimental"), Anda memiliki beberapa opsi untuk menggunakan ESM ( E CMA S cript M odules) di Node.js (untuk file, ada cara ketiga untuk menghindari string), inilah yang dikatakan dokumentasi :

The --experimental-modulesflag dapat digunakan untuk mengaktifkan dukungan untuk ECMAScript modul (ES modul).

Setelah diaktifkan, Node.js akan memperlakukan yang berikut ini sebagai modul ES ketika diteruskan nodesebagai input awal, atau ketika direferensikan oleh importpernyataan dalam kode modul ES:

  • File berakhiran .mjs.

  • File yang berakhiran .js, atau file tanpa ekstensi, ketika package.jsonfile induk terdekat berisi bidang tingkat atas "type"dengan nilai "module".

  • String diteruskan sebagai argumen ke --evalatau --print, atau disalurkan nodemelalui STDIN, dengan bendera --input-type=module.

Node.js akan memperlakukan sebagai CommonJS semua bentuk input lainnya, seperti .jsfile di mana file induk terdekat package.jsontidak berisi "type" bidang level atas , atau input string tanpa flag --input-type. Perilaku ini untuk menjaga kompatibilitas ke belakang. Namun, sekarang Node.js mendukung modul CommonJS dan ES, yang terbaik adalah bersikap eksplisit jika memungkinkan. Node.js akan memperlakukan yang berikut ini sebagai CommonJS ketika diteruskan ke nodesebagai input awal, atau ketika direferensikan oleh importpernyataan dalam kode modul ES:

  • File berakhiran .cjs.

  • File yang berakhiran .js, atau file tanpa ekstensi, ketika package.jsonfile induk terdekat berisi bidang tingkat atas "type"dengan nilai "commonjs".

  • String diteruskan sebagai argumen ke --evalatau --print, atau disalurkan nodemelalui STDIN, dengan bendera --input-type=commonjs.

TJ Crowder
sumber
3

Ketika saya mulai dengan express selalu menginginkan solusi untuk menggunakan impor bukannya memerlukan

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

Banyak waktu melewati baris ini: - Unfortunately, Node.js doesn't support ES6's import yet.

Sekarang untuk membantu yang lain, saya membuat dua solusi baru di sini

1) ESM : -

Pemuat modul ECMAScript yang sederhana, tanpa label, tanpa bundel. mari kita membuatnya bekerja

  yarn add esm / npm install esm

buat start.js atau gunakan namespace Anda

 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

Ubah package.josnjalur pass Anda daristart.js

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

2) Babel js : -

Ini dapat dibagi menjadi 2 bagian

a) Solusi 1 berkat timonweb.com

b) Solusi 2

gunakan Babel 6 (versi lama dari babel-preset-stage-3 ^ 6.0 ) buat .babelrcfile di folder root Anda

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

Instal babel-preset-stage-3

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

Ubah 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"
},

Mulai server Anda

yarn start / npm start

Oooh tidak, kami menciptakan masalah baru

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

Kesalahan ini hanya terjadi ketika Anda menggunakan async / menunggu dalam kode Anda. Kemudian gunakan polyfill yang menyertakan runtime regenerator kustom dan core-js. tambahkan di atasindex.js

import "babel-polyfill"

Ini memungkinkan Anda untuk menggunakan async / menunggu

gunakan Babel 7

Perlu memperbarui setiap hal dalam proyek Anda, mari kita mulai dengan babel 7 .babelrc

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

Beberapa perubahan pada 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"
....
}

dan gunakan import "@babel/polyfill"pada titik awal

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

Apakah kamu berpikir mengapa start:dev

Serius. Ini pertanyaan yang bagus jika Anda baru. Setiap perubahan Anda babi dengan server mulai setiap kali kemudian digunakan yarn start:devsebagai server pengembangan setiap perubahan restart server secara otomatis untuk lebih lanjut tentang nodemon

Ashok
sumber
2

Dalam kasus saya itu sedang mencari .babelrcfile, dan itu harus berisi sesuatu seperti ini:

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