SyntaxError: ไม่สามารถใช้คำสั่งนำเข้านอกโมดูล


53

ฉันมีโครงการ ApolloServer ที่ทำให้ฉันมีปัญหาดังนั้นฉันจึงคิดว่าฉันอาจอัปเดตและพบปัญหาเมื่อใช้ Babel ล่าสุด "index.js" ของฉันคือ:

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

และเมื่อฉันเรียกใช้ฉันได้รับข้อผิดพลาด "SyntaxError: ไม่สามารถใช้คำสั่งนำเข้านอกโมดูล" ก่อนอื่นฉันพยายามทำสิ่งต่าง ๆ เพื่อโน้มน้าวใจ TPTB * ว่านี่เป็นโมดูล (ไม่สำเร็จ) ดังนั้นฉันจึงเปลี่ยน "นำเข้า" เป็น "ต้องการ" และใช้งานได้

แต่ตอนนี้ฉันมี "การนำเข้า" ประมาณสองโหลในไฟล์อื่นทำให้ฉันมีข้อผิดพลาดเดียวกัน

* ฉันแน่ใจว่าสาเหตุของปัญหาคือฉันไม่แน่ใจด้วยซ้ำว่ามีอะไรบ่นเกี่ยวกับปัญหานี้ ฉันคิดว่ามันคือบาเบล 7 (ตั้งแต่ฉันมาจากบาเบล 6 และฉันต้องเปลี่ยนค่าที่ตั้งไว้ล่วงหน้า) แต่ฉันไม่แน่ใจ 100%

สิ่งที่ฉันพบวิธีแก้ปัญหาส่วนใหญ่ดูเหมือนจะไม่ใช้กับโหนดตรง ชอบอันนี้ที่นี่:

โมดูล ES6 นำเข้าที่ให้ "Uncaught SyntaxError: ตัวระบุที่ไม่คาดคิด"

บอกว่ามันได้รับการแก้ไขโดยการเพิ่ม "type = module" แต่โดยทั่วไปแล้วสิ่งนี้จะอยู่ใน HTML ซึ่งฉันไม่มีเลย ฉันได้ลองใช้การตั้งค่าล่วงหน้าของโครงการแล้ว:

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

แต่นั่นทำให้ฉันเกิดข้อผิดพลาดอีกครั้ง: "ข้อผิดพลาด: ไฟล์ปลั๊กอิน / ที่ตั้งไว้ล่วงหน้าไม่ได้รับอนุญาตให้ส่งออกวัตถุเพียงฟังก์ชั่นเท่านั้น"

UPDATE: นี่คือการอ้างอิงที่ฉันเริ่มต้นด้วย:

"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
สวัสดีมีปัญหาเดียวกันตอนนี้ คุณสามารถแบ่งปันการพึ่งพาของคุณได้หรือไม่? อาจแตกต่างกันทั้งก่อนและหลังการอัพเดทของคุณ ฉันสามารถตรวจสอบกับฉันเพื่อดูว่าเราสามารถหาแพ็คเกจที่คล้ายกันซึ่งอาจทำให้เกิดปัญหา
คม

ฉันเพิ่งแทนที่ "การนำเข้า" ทั้งหมดด้วย "ต้องการ" และตอนนี้ทั้งหมดก็เรียบร้อยแล้ว โง่ แต่มันก็ไม่คุ้มค่าที่จะคิดออกตอนนี้ ฉันจะอัปเดตต้นฉบับด้วยการอ้างอิงแม้ว่า หากคุณได้รับโอกาสในการขายใด ๆ ฉันจะตรวจสอบกับรหัสต้นฉบับของฉัน
user3810626

1
ไวยากรณ์ CommonJS (ต้องการและ module.exports) เป็นรูปแบบดั้งเดิมสำหรับโหนดและ webpack ยังรองรับ แต่ไวยากรณ์โมดูล ES6 (ส่งออกนำเข้า) เป็นวิธีที่ใหม่กว่าและตอนนี้โหนดและ webpack สนับสนุน ฉันอ่านแล้วว่าโหนดรองรับการนำเข้าตอนนี้ แต่บทเรียนจำนวนมากแสดงให้เห็นว่าจำเป็นต้องใช้โหนดที่บริสุทธิ์ซึ่งน่าจะดีกว่าถ้าใช้ไวยากรณ์นั้นสำหรับโหนด
Ted Fitzpatrick

1
ในที่สุดสำหรับฉันวิธีที่จะไปดูเหมือนจะเป็นเช่นนี้: github.com/vuejs/vue-jest/issues/134#issuecomment-461755061 การตั้งค่าล่วงหน้าjest.config.jsเป็น'ts-jest/presets/js-with-ts'- ยังมีปัญหาอื่น ๆ อีก แต่สิ่งนี้แก้ไขปัญหาใหญ่ได้แล้ว ..... เอ่อเออปัญหาของฉันได้รับการทดสอบที่เกี่ยวข้อง ... ปกติสร้างได้ดี
คม

คมน่าสนใจ ไม่ได้ใช้ Jest ด้วยตัวเอง เท็ดน่าสนใจ ตกลงฉันจะไม่เหงื่อ
user3810626

คำตอบ:


50

2020 Update (โหนด 13.2.0+)

ตรวจสอบว่าคุณได้ติดตั้งโหนดเวอร์ชันล่าสุด --experimental-modulesธงไม่จำเป็น ทำอย่างใดอย่างหนึ่งต่อไปนี้ :

  • เพิ่มไปยังผู้ปกครองที่ใกล้ที่สุด"type": "module" package.jsonด้วยวิธีนี้ทั้งหมด.jsและ.mjsไฟล์จะถูกตีความเป็นโมดูล ES คุณสามารถตีความแต่ละไฟล์เป็น CommonJS โดยใช้.cjsส่วนขยาย

หรือ

  • อย่างชัดเจนชื่อไฟล์ที่มี.mjsนามสกุล ไฟล์อื่นทั้งหมดเช่น.jsจะถูกตีความเป็น CommonJS ซึ่งเป็นค่าเริ่มต้นหากtypepackage.jsonไม่ได้กำหนดใน

หากฉันใช้สิ่งนี้ให้เปลี่ยนพา ธ เพื่อรวม "js" สำหรับไฟล์ที่ต้องการจากนั้นเปลี่ยนรูปแบบของคำสั่งการส่งออกในไฟล์ที่ต้องการจากนั้นใช้คำสั่ง "ต้องการ" ทั้งหมดที่ฉันเปลี่ยนจาก "นำเข้า" - เนื่องจาก ไม่ทราบว่า "ต้องการ" ตอนนี้จะใช้ได้ดังนั้นฉันจะยอมรับคำตอบนี้
user3810626

2
นี่ไม่ใช่ตัวเลือกจริง ๆ ถ้าปัญหาอยู่ภายใต้ node_modules / ใช่มั้ย ความคิดใด ๆ วิธีการแก้ไขในกรณีที่?
Trent Bing

18

ตามเอกสารอย่างเป็นทางการ ( https://nodejs.org/api/esm.html#esm_code_import_code_statements ):

คำสั่งนำเข้าได้รับอนุญาตเฉพาะในโมดูล ES สำหรับฟังก์ชันการทำงานที่คล้ายกันใน CommonJS โปรดดูที่การนำเข้า ()

ในการทำให้โหนดปฏิบัติต่อไฟล์ของคุณเป็นโมดูล ES คุณต้อง ( https://nodejs.org/api/esm.html#esm_enabling ):

  • เพิ่ม "type": "module" ไปยัง package.json
  • เพิ่มแฟล็ก "--experimental-modules" ไปยังการเรียกโหนด

6

ฉันมีปัญหาเดียวกันและต่อไปนี้แก้ไขได้ (โดยใช้โหนด 12.13.1):

  • เปลี่ยนนามสกุลไฟล์. js เป็น. mjs
  • เพิ่ม - ตั้งค่าสถานะโมดูลเมื่อเรียกใช้แอปของคุณ
  • ทางเลือก: เพิ่ม "type": "module" ใน package.json ของคุณ

ข้อมูลเพิ่มเติม: https://nodejs.org/api/esm.html


0

ฉันมีปัญหานี้ในโครงการ Express API ที่มีประสบการณ์

รหัสเซิร์ฟเวอร์ที่ละเมิดใน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...'));

นี่คือการพึ่งพาของฉัน:

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

และนี่คือนักวิ่งที่ทำให้เกิดข้อผิดพลาด:

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

มันน่าผิดหวังเพราะฉันมีโครงการ Express ที่คล้ายกันซึ่งใช้งานได้ดี

วิธีแก้ไขปัญหาแรกเพิ่มการพึ่งพานี้:

npm install @babel/preset-env

จากนั้นให้ทำการโยงโดยใช้ a babel.config.jsในรูทโปรเจ็กต์:

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

ฉันไม่เข้าใจว่าทำไมงานนี้ถึงสมบูรณ์ แต่ฉันคัดลอกมาจากแหล่งที่เชื่อถือได้ดังนั้นฉันจึงดีใจที่ติดกับมัน


ใช่ปัญหาของผมก็คือว่ารหัสมีพวงจากที่ตั้งไว้และฉันจะไม่เคยตีค่อนข้างสมดุลของสิ่งที่ผมอยากเทียบกับสิ่งที่ฉันไม่ต้องการ / สิ่งที่ยากจน
user3810626

ฉันผลักดันให้เกิดปัญหา JS สับสนตลอดทั้งวัน @ user3810626 - ฉันสงสัยว่าปัญหาของฉันคือว่าฉันค่อนข้างใหม่กับภาษาและระบบนิเวศและฉันต้องหยุดการเรียนรู้เพื่อให้สิ่งต่าง ๆ ทำงานได้ในตอนนี้ การเดินทาง ...:-)
halfer

1
โชคดี! มันเป็นป่า! (ฉันหมายถึงแท้จริงระบบนิเวศ JS เป็นป่า ... )
user3810626

-2
  1. ฉันมีปัญหาเดียวกันเมื่อฉันเริ่มใช้ babel ... แต่ต่อมาฉันมีวิธีแก้ปัญหา ... ฉันไม่ได้มีปัญหาอีกต่อไปจนถึงตอนนี้ ... ปัจจุบันโหนด v12.14.1, "@ babel / node" : "^ 7.8.4" ฉันใช้ babel-node และ nodemon เพื่อดำเนินการ (โหนดก็ใช้ได้เช่นกัน .. )
  2. package.json: "start": "nodemon --exec babel-node server.js" debug ":" babel-node debug server.js "!! note: server.js เป็นไฟล์บันทึกของฉันคุณสามารถใช้ของคุณได้
  3. launch.jsonเมื่อคุณดีบักคุณต้องกำหนดค่าไฟล์ launch.json ของคุณ "runtimeExecutable": "$ {workspaceRoot} /node_modules/.bin/babel-node" !!
  4. แน่นอนว่าด้วย babel-node โดยปกติแล้วคุณจะต้องใช้และแก้ไขไฟล์อื่นเช่น babel.config.js / .babelrc

-2

วิธีแก้ปัญหาของฉันคือการรวมเส้นทางของ babel-node ขณะที่เรียกใช้ nodemon ดังนี้

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

คุณสามารถเพิ่มสคริปต์ package.json ของคุณเป็น:

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

หมายเหตุ: ไฟล์รายการของฉันคือindex.jsแทนที่ด้วยไฟล์รายการของคุณ (หลายคนมี app.js / server.js)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.