Node.js - Sözdizimi Hatası: Beklenmeyen simge içe aktarma


443

Neyin yanlış olduğunu anlamıyorum. Düğüm v5.6.0 NPM v3.10.6

Kod:

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

Hata:

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
Düğümlerde yerel olarak desteklenmediği için Nodejs'de içe aktarmayı kullanmak için Babel gibi bir transpiler kullanın.İthalatın en iyi alternatifi bu yüzden bununla gidin.
BHUVNESH KUMAR

Yanıtlar:


484

Güncelleştirme 3: Düğüm 13'ten bu yana , .mjs uzantısını kullanabilir veya package.json dosyasında "type": "module" ayarını kullanabilirsiniz. Sen yok kullanmak gerekir --experimental-modulesbayrağı.

Güncelleştirme 2: Düğüm 12'den bu yana , .mjsuzantıyı kullanabilir veya "type": "module"paketinizde ayarlayabilirsiniz . Json. Ve --experimental-modulesbayrakla düğüm çalıştırmanız gerekiyor .

Güncelleme: In Düğüm 9 , bir bayrak arkasında etkin ve kullanır .mjsuzantısı.

node --experimental-modules my-app.mjs

importGerçekten de ES6'nın bir parçası olsa da, ne yazık ki NodeJS'de varsayılan olarak henüz desteklenmemektedir ve tarayıcılarda çok yakın zamanda destek almıştır.

Bkz MDN'yi tarayıcı compat tablosunu ve bu Düğüm sorunu .

Node.js'deki James M Snell'in ES6 Modülleri Güncellemesinden (Şubat 2017):

İşler sürüyor ama biraz zaman alacak - Şu anda en azından bir yıla bakıyoruz.

Destek yerel olarak görünene kadar klasik requireifadeleri kullanmaya devam etmeniz gerekir :

const express = require("express");

NodeJS'de gerçekten yeni ES6 / 7 özelliklerini kullanmak istiyorsanız, Babel'i kullanarak derleyebilirsiniz. İşte bir örnek sunucu .


2
10 numaralı düğümün varsayılan olarak etkinleştirilmiş destekle gelip gelmeyeceğini bilen var mı? (önümüzdeki ay
Hartmut

2
@Scimonster ...... düğüm - deneysel modüller my-app.mjs (düğüm: 12176) Deneysel Uyarı: ESM modülü yükleyicisi deneyseldir. {Hata: Modül /C:/Users/WittyParrot/Documents/card-test-project/src/my-app.mjs aramada bulunamadı (dahili / modüller / esm / DefaultResolve.js: 23: 12) test projesi / src / my-app.mjs aramada (internal / modules / esm / DefaultResolve.js: 23: 12) .... bir uyarı atmak my-app.js'yi bulamadı .... lütfen önerin .... i yüklü düğüm sürümü 9.11.1
Leo

52
sinir bozucu çünkü orada öğreticiler çoğunluğu ithalat kullanarak konuşmak, ama neredeyse hiç destek yoktur. (Hayatımın 2 saat geri lol istiyorum)
kiwicomb123

9
@ChaimEliyah: v11.0.0 düğümünde aynı sorunu var
whoami


60

Ne yazık ki, Node.js importhenüz ES6'ları desteklemiyor .

Yapmaya çalıştığınız şeyi gerçekleştirmek için (Express modülünü içe aktarın), bu kod yeterli olmalıdır

var express = require("express");

Ayrıca, çalıştırarak Express'in yüklü olduğundan emin olun

$ npm install express

Node.js'yi öğrenmek hakkında daha fazla bilgi için Node.js Dokümanlarına bakın.


8
importmutlaka bir TypeScript özelliği değildir. TypeScript yazım içeren ES6'dır. Yani ithalat gibi şeyler ES6 yerli.
16:11

@borislemke Doğru, OP'yi biraz yanlış yorumladım. :) Ben değiştireceğim.
baranskistad

merhaba, ekspres yükledim ama package.json dosyasının komut dosyasında ne yazmalıyız? "Scripts": {"start": "node index.js"} yazarsam, aynı hatayı görüntülemelidir. Lütfen bana yardım et.
Ravi Shah

node index.jsbenim için çalışıyor, ama ben çalıştırdığınızda node dist/main.jsben de olsun Unexpected token import.
TheFox

@TheFox muhtemelen bu dosyada bir içe aktarma işleminiz var. Sadece index.jsgeçiyor olmanız da sizin dist/main.jsgeçeceğiniz anlamına gelmez .
baranskistad

34

Diğer yanıtlarda belirtildiği gibi, Node JS şu anda ES6 ithalatını desteklememektedir.

(Şu andan itibaren EDIT 2'yi okuyun)

Js düğümünde ES6 içe aktarmayı etkinleştir bu soruna bir çözüm sağlar. Bunu denedim ve benim için çalıştı.

Komutu çalıştırın:

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

Şimdi yeni bir dosya (config.js) oluşturmanız ve bu dosyaya aşağıdaki kodu eklemeniz gerekir.

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

Artık herhangi bir hata almadan import ifadeleri yazabilirsiniz.

Bu yardımcı olur umarım.

DÜZENLE:

Yukarıdaki kodla oluşturduğunuz yeni dosyayı çalıştırmanız gerekir. Benim durumumda öyleydi config.js. Bu yüzden koşmam gerekiyor:

    node config.js

DÜZENLEME 2:

Deneme yaparken, bu soruna kolay bir çözüm buldum.

.babelrcProjenizin kök dizininde dosya oluşturun .

Aşağıdakileri ekleyin (ve ihtiyacınız olan diğer babel hazır ayarları bu dosyaya eklenebilir):

    {
        "presets": ["env"]
    }

babel-preset-envKomut kullanarak yükle npm install babel-preset-env --saveve ardından babel-clikomut kullanarak yüklenpm install babel-cli -g --save

Şimdi sunucunuzun veya dizin dosyanızın bulunduğu klasöre gidin ve şunu kullanarak çalıştırın: babel-node fileName.js

Veya dosyanıza npm startaşağıdaki kodu ekleyerek kullanabilirsiniz package.json:

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

Bunu elektronla nasıl yapabilirim? Ben böyle denedim: "start": "babel-node electron .", ama şanssız
tpbafk

2
@tpbafk Elektron üzerinde çalışmadım. Ama senin sorunun javascript benzer bir şey buldum - 'babel-node --presets es2015, sahne-3' ile elektron uygulaması için npm başlangıç ​​nasıl ayarlanır . Umut etmek o yardım etmek
Neerali Acharya

33

Hata: Sözdizimi Hatası: Beklenmedik belirteç içe aktarma veya Sözdizimi Hatası: Beklenmedik belirteç dışa aktarma


Çözüm: Tüm içe aktarmalarınızı örnek olarak değiştirin

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

Ve ayrıca değiştirmek export default = foo;Tomodule.exports = foo;


1
İhracat varsayılan bölümünü biraz daha açıklasaydınız. Bu kısımda sorun yaşıyorum. İçe aktarma cevabınızla harika çalışıyor.
JoeGalind

Cevabımdan önce bir açıklaması olan bir cevap var. Ancak açıklama için Düğüm ES6 sözdizimini desteklemez. Import ... ES6 sözdizimini kullandığınızda
supritshah1289

22

Şok olduğum esmsöylenmedi. Bu küçük ama güçlü paket ya importda kullanmanıza izin verir require.

Projenize esm yükleyin

$ npm install --save esm

Düğüm Başlatma Komut Dosyanızı esm kullanmak üzere güncelleyin

node -r esm app.js

esmsadece çalışır. Bir TON ile zaman harcadım .mjsve --experimental-modulessadece bir .mjsdosyayı bulmak için requireveya kullanan bir dosyayı alamaz module.exports. Bu çok büyük bir sorundu, oysa esmkarıştırmanıza ve eşleştirmenize izin veriyor ve sadece çözüyor ... esmsadece çalışıyor.


17

Hala "import" kullanamıyorsanız işte ben nasıl ele: Sadece bir düğüm dostu gerektirir çevirmek. Misal:

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

Aynıdır:

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

4
(büyük olasılıkla olduğu gibi) exportanahtar kelimesini kullanıyorsanız doğru değil
Daniel Thompson

@DanielThompson Üzgünüm, bu yanlış anlama olabilir, sadece bu durum için bir geçici çözüm veriyorum, exportanahtar kelime olmadan çalışırsanız, yine de yararlı notunuz için teşekkürler!
Alberto

Benim için çalışıyorum. Teşekkürler
Ali Azhar

11

babel 7 teklifi dev bağımlılıkları ekleyebilir

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

ve kök dizinine bir .babelrc ekleyin

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

ve .js dosyasına ekleyin

require("@babel/register")

ya da klibi çalıştırırsanız, gerekli kanca -r @ babel / register olarak kullanabilirsiniz, örn.

$node -r @babel/register executeMyFileWithESModules.js

1
@ Babel / preset-env'yi yüklemek ve .babelrc'ye eklemek hile yaptı. Benim durumumda @ babel / register eklentisine gerek yok.
Marcos R

8

'babel' kullanabiliyorsanız, aşağıdaki gibi package.json (- presets = es2015) dizinine komut dosyaları eklemeyi deneyin. ithalat kodunu es2015'e önceden derlemek

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

ama npm startönce "derlemeyi" mi yoksa ilk olarak "başlat" ı mı arayacağım ? (Başlangıç ​​şu anda tanımlanmıştır:"nodemon src/app.js --exec \"npm run lint && node\"",
pashute

Bu cmd çalıştırırsanız, sunucu hatası yok gösterir
kumaresan_sd

6

Node.js v12'den itibaren (ve bu muhtemelen oldukça kararlı, ancak yine de "deneysel" olarak işaretlenmiş), Node.js'de ESM ( E CMA S cript M odules) kullanmak için birkaç seçeneğiniz var (dosyalar için, dizeleri değerlendirmenin üçüncü yolu), dokümantasyon şöyle diyor:

--experimental-modulesBayrak ECMAScript modüllerinin (ES modüller) için destek sağlamak için kullanılabilir.

Etkinleştirildiğinde, Node.js nodeilk giriş olarak iletildiğinde veya importES modül kodundaki ifadelerle başvurulduğunda aşağıdakileri ES modülleri olarak ele alır :

  • İle biten dosyalar .mjs.

  • .jsEn yakın üst package.jsondosya "type"değeri olan bir üst düzey alan içerdiğinde , biten dosyalar veya uzantısız dosyalar "module".

  • Yaylı bir bağımsız değişken olarak geçirilen --evalya da --print, ya da borulu nodeile STDINbayrak, --input-type=module.

Node.js, .jsen yakın üst package.jsondosyanın üst düzey "type" alan içermediği dosyalar veya bayraksız dize girdisi gibi diğer tüm girdi biçimlerini CommonJS olarak kabul eder --input-type. Bu davranış, geriye dönük uyumluluğu korumaktır. Ancak, Node.js artık hem CommonJS hem de ES modüllerini desteklediğine göre, mümkün olduğunda açık olmak en iyisidir. Node.js node, ilk girdi olarak iletildiğinde veya importES modül kodundaki ifadelerle başvurulduğunda aşağıdakileri CommonJS olarak ele alır :

  • İle biten dosyalar .cjs.

  • .jsEn yakın üst package.jsondosya "type"değeri olan bir üst düzey alan içerdiğinde , biten dosyalar veya uzantısız dosyalar "commonjs".

  • Yaylı bir bağımsız değişken olarak geçirilen --evalya da --print, ya da borulu nodeile STDINbayrak, --input-type=commonjs.


3

Express ile başladığımda her zaman ithalat kullanmak için bir çözüm istedi

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

Birçok zaman bu çizgiden geçiyor: - Unfortunately, Node.js doesn't support ES6's import yet.

Şimdi diğerlerine yardım etmek için burada yeni iki çözüm üretiyorum

1) esm : -

Zekice basit, babasız, demetsiz ECMAScript modül yükleyici. hadi çalışmasını sağlayalım

  yarn add esm / npm install esm

start.js oluşturun veya ad alanınızı kullanın

 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

package.josnGeçiş yolunuzdaki değişiklikstart.js

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

2) Babil js : -

Bu 2 kısma ayrılabilir

a) timonweb.com sayesinde çözüm 1

b) Çözüm 2

Babel 6'yı kullanın ( babel-preset-stage-3 ^ 6.0'ın eski sürümü ) .babelrckök klasörünüzde dosya oluşturun

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

Babel-preset-stage-3 yazılımını yükleyin

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

Package.json dosyasındaki değişiklik

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

Sunucunuzu başlatın

yarn start / npm start

Oooh hayır yeni bir problem yaratıyoruz

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

Bu hata yalnızca kodunuzda async / await kullandığınızda gelir. Sonra özel bir rejeneratör çalışma zamanı ve core-js içeren çoklu dolgu kullanın. üstüne ekleindex.js

import "babel-polyfill"

Bu, zaman uyumsuz / beklemede kullanmanızı sağlar

Kullanım Babel 7

Projenizdeki her şeyin babel 7 .babelrc ile başlamasına izin vermeniz gerekiyor

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

Package.json dosyasında bazı değişiklikler

"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"
....
}

ve import "@babel/polyfill"başlangıç ​​noktasında kullanın

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

Neden olduğunu düşünüyor musun start:dev

Ciddi anlamda. Eğer yeniyseniz iyi bir soru. Her seferinde başlangıç ​​sunucusu ile domuzu yaptığınız her değişiklik yarn start:dev, geliştirme sunucusu olarak her değişiklik sunucusunu otomatik olarak yeniden başlatır.


2

Benim durumumda .babelrcdosya bakıyordu ve böyle bir şey içermelidir:

{
  "presets": ["es2015-node5", "stage-3"],
  "plugins": []
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.