SyntaxError: Tidak dapat menggunakan pernyataan impor di luar modul


53

Saya punya proyek ApolloServer yang memberi saya masalah, jadi saya pikir saya mungkin memperbaruinya dan mengalami masalah ketika menggunakan Babel terbaru. "Index.js" saya adalah:

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

Dan ketika saya menjalankannya saya mendapatkan kesalahan "SyntaxError: Tidak dapat menggunakan pernyataan impor di luar modul". Pertama saya mencoba melakukan hal-hal untuk meyakinkan TPTB * bahwa ini adalah modul (tidak berhasil). Jadi saya mengubah "impor" menjadi "memerlukan" dan ini berhasil.

Tapi sekarang saya memiliki sekitar dua lusin "impor" di file lain yang memberi saya kesalahan yang sama.

* Saya yakin akar masalah saya adalah bahwa saya bahkan tidak yakin apa yang mengeluh tentang masalah ini. Saya berasumsi itu adalah Babel 7 (karena saya berasal dari Babel 6 dan saya harus mengubah preset) tetapi saya tidak 100% yakin.

Sebagian besar dari apa yang saya temukan untuk solusi tampaknya tidak berlaku untuk Node lurus. Seperti ini di sini:

Modul ES6 Impor yang memberikan "Sintaks Tanpa PerintahError: Pengidentifikasi tak terduga"

Mengatakan itu diselesaikan dengan menambahkan "type = module" tetapi ini biasanya akan masuk dalam HTML, yang saya tidak punya. Saya juga mencoba menggunakan preset lama proyek saya:

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

Tapi itu membuat saya kesalahan lain: "Kesalahan: File Plugin / Preset tidak diizinkan untuk mengekspor objek, hanya fungsi."

UPDATE: Ini adalah dependensi yang saya mulai dengan:

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

1
Hai, mengalami masalah yang sama sekarang. Bisakah Anda juga membagikan dependensi Anda? Mungkin bahkan beda sebelum dan sesudah pembaruan Anda. Saya dapat memeriksa milik saya untuk melihat apakah kami dapat menemukan paket serupa yang dapat menyebabkan masalah.
lynx

Saya baru saja mengganti semua "impor" dengan "memerlukan" dan semuanya baik-baik saja sekarang. Bodoh tetapi tidak sepadan dengan upaya untuk mencari tahu sekarang. Saya akan memperbarui yang asli dengan dependensi. Jika Anda mendapatkan petunjuk, saya akan memeriksanya dengan kode asli saya.
user3810626

1
Sintaks CommonJS (memerlukan dan module.exports) adalah format asli untuk node dan webpack juga mendukungnya, tetapi sintaksis modul ES6 (ekspor, impor) adalah cara yang lebih baru dan sekarang node dan webpack mendukungnya. Saya membaca bahwa simpul mendukung impor sekarang, tetapi begitu banyak tutorial menunjukkan perlunya hal-hal simpul murni yang sepertinya lebih baik untuk menggunakan sintaks untuk simpul tersebut.
Ted Fitzpatrick

1
Akhirnya, bagi saya cara untuk pergi sepertinya adalah ini: github.com/vuejs/vue-jest/issues/134#issuecomment-461755061 Mengatur preset jest.config.jske 'ts-jest/presets/js-with-ts'- masih memiliki beberapa masalah lain tetapi ini menyelesaikan yang besar. ..... eh ya, masalah saya adalah pengujian terkait ... build normal baik-baik saja
lynx

Lynx, Menarik. Tidak menggunakan Jest, saya sendiri. Ted, menarik. Oke, saya tidak akan berkeringat.
user3810626

Jawaban:


52

Pembaruan 2020 (Node 13.2.0+)

Pastikan Anda telah menginstal Node versi terbaru. The --experimental-modulesflag tidak lagi diperlukan. Cukup lakukan salah satu dari yang berikut :

  • Tambahkan "type": "module"ke induk terdekat package.json. Dengan ini, semua .jsdan .mjsfile ditafsirkan sebagai modul ES. Anda dapat mengartikan file individual sebagai CommonJS dengan menggunakan .cjsekstensi.

ATAU

  • Beri nama file dengan .mjsekstensi secara eksplisit . Semua file lain, seperti .jsakan ditafsirkan sebagai CommonJS, yang merupakan default jika typetidak didefinisikan dalam package.json.

Jika saya menggunakan ini, maka ubah jalur untuk menyertakan "js" untuk file yang diperlukan, kemudian ubah format pernyataan ekspor dalam file yang diperlukan, dan kemudian ambil semua "memerlukan" pernyataan yang saya ubah dari "impor" —karena sekarang "wajib" tidak dikenal — ini akan berhasil, jadi saya akan menerima jawaban ini.
user3810626

2
Ini sebenarnya bukan opsi jika masalahnya ada di bawah node_modules / benar? Ada ide bagaimana cara memperbaikinya?
Trent Bing


6

Saya memiliki masalah yang sama dan berikut ini telah memperbaikinya (menggunakan simpul 12.13.1):

  • Ubah ekstensi file .js menjadi .mjs
  • Tambahkan flag --experimental-modul saat menjalankan aplikasi Anda.
  • Opsional: tambahkan "type": "module" di package.json Anda

info lebih lanjut: https://nodejs.org/api/esm.html


0

Saya mengalami masalah ini dalam proyek Express API yang masih baru.

Kode server yang menyinggung di 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...'));

Inilah ketergantungan saya:

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

Dan inilah pelari yang melempar kesalahan:

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

Ini menyebalkan, karena saya memiliki proyek Express serupa yang bekerja dengan baik.

Solusinya adalah pertama-tama menambahkan ketergantungan ini:

npm install @babel/preset-env

Dan kemudian babel.config.jsmenghubungkannya menggunakan root proyek:

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

Saya tidak sepenuhnya mengerti mengapa ini berhasil, tetapi saya menyalinnya dari sumber yang berwenang , jadi saya senang menggunakannya.


Ya, masalah saya adalah bahwa kode memiliki banyak preset dan saya tidak pernah bisa mencapai keseimbangan dengan hal-hal yang saya inginkan vs. hal-hal yang tidak saya inginkan / hal-hal yang rusak.
user3810626

Saya telah mendorong melalui crash JS membingungkan sepanjang hari @ user3810626 - Saya menduga masalah saya adalah bahwa saya cukup baru untuk bahasa dan ekosistem, dan saya perlu mengesampingkan pembelajaran untuk saat ini agar barang berfungsi. Cara ke sana ...:-)
halfer

1
Semoga berhasil! Itu hutan di luar sana! (Maksud saya, secara harfiah, ekosistem JS adalah hutan ...)
user3810626

-2
  1. Saya memiliki masalah yang sama ketika saya mulai menggunakan babel ... Tapi kemudian, saya punya solusi ... Saya tidak punya masalah lagi sejauh ini ... Saat ini, Node v12.14.1, "@ babel / node" : "^ 7.8.4", saya menggunakan babel-node dan nodemon untuk mengeksekusi (node ​​juga baik-baik saja ..)
  2. package.json: "start": "nodemon --exec babel-node server.js" debug ":" babel-node debug server.js "!! catatan: server.js adalah file entri saya, Anda dapat menggunakan milik Anda.
  3. launch.json Ketika Anda melakukan debug, Anda juga perlu mengkonfigurasi file launch.json Anda "runtimeExecutable": "$ {workspaceRoot} /node_modules/.bin/babel-node" !! catatan: plus runtimeExecutable ke dalam konfigurasi.
  4. Tentu saja, dengan babel-node, Anda biasanya juga perlu dan mengedit file lain, seperti file babel.config.js / .babelrc

-2

Solusi saya adalah memasukkan babel-node path sambil menjalankan nodemon sebagai berikut:

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

Anda dapat menambahkan skrip package.json Anda sebagai:

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

CATATAN: File entri saya adalah index.js ganti dengan file entri Anda (banyak yang memiliki app.js / server.js).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.