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


19

ฉันมีไฟล์. ts ในโหนด js (เวอร์ชันล่าสุดของ node.js สำหรับ 07.10.19) ที่มีการนำเข้าโหนดโมดูลโดยไม่มีการส่งออกเริ่มต้น ผมใช้การก่อสร้างนี้: เมื่อฉันเรียกใช้รหัสฉันมีข้อผิดพลาดนี้:import { Class } from 'abc';Cannot use import statement outside a module

ในเครือข่ายฉันเห็นวิธีแก้ปัญหามากมายสำหรับปัญหานี้ (สำหรับ. js) แต่มันไม่ได้ช่วยอะไรฉันบางทีอาจเป็นเพราะฉันมีไฟล์ typescript นี่คือรหัสของฉัน:

import { Class } from 'abc';
module.exports = { ...
    execute(a : Class ,args : Array<string>){ ...

นี่คือ tsconfig.json ของฉัน:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",

    "strict": true
  }
}

คุณใช้งานเบราว์เซอร์นี้หรือไม่? เป็นimportคำสั่งบรรทัดแรกในไฟล์ของคุณ?
ปลิ้น

1
คุณช่วยโพสต์ไฟล์ tsconfig.json ของคุณได้ไหม เมื่อคุณรวบรวมใน typescript คุณสามารถกำหนดประเภทของโมดูลที่ผลิตและประเภทที่ถูกต้องอาจแตกต่างกันไปขึ้นอยู่กับสภาพแวดล้อม (เบราว์เซอร์ / NodeJS) และโมดูลอื่น ( requirevs import) ที่คุณใช้ เพียงเพื่อให้คุณเข้าใจว่ามันซับซ้อนแค่ไหน Node มีเอกสารเกี่ยวกับimportvs requireและวิธีทำให้พวกเขาทำงานร่วมกันได้
Jeff Bowman

1
หากคุณใช้module.exportsไวยากรณ์คุณอาจไม่ได้อยู่ในโมดูล ES6
Bergi

หลีกเลี่ยงนี่คือแอป node js โดยจะเพิ่ม
tsconfig

ตกลงฉันไม่สามารถใช้ได้ต้องใช้เพราะไม่สามารถค้นหาเนมสเปซ 'abc' เมื่อใช้งานการก่อสร้างexecute(a : abc.Class...
4321

คำตอบ:


5

การเพิ่ม“type”: “module”ไปยัง package.jsonจะบอก Node ว่าคุณกำลังใช้โมดูล ES2015 ซึ่งควรกำจัดข้อผิดพลาด แต่จากนั้นคุณจะต้องบอก typescript เพื่อสร้างโมดูลประเภทนี้โดยการตั้งค่า“module”: “es2015”แทน“commonjs”ใน tsconfig.json

อย่างไรก็ตามสิ่งนี้ทำให้เกิดปัญหากับรหัสปัจจุบันเพราะแม้ว่าคุณจะใช้import {}คำสั่งES6 คุณกำลังส่งออกโดยใช้module.exports = {}ไวยากรณ์commonJS และตัวโหลดโมดูล ES ของโหนดจะมีปัญหากับมัน มีสองวิธีในการจัดการกับมัน:

  1. เก็บmodule.exportsแต่แจ้งให้ Node ตีความไฟล์นี้เป็น commonJS โดยให้นามสกุลเป็น . cjs
  2. เปลี่ยนคำสั่งส่งออกเป็นไวยากรณ์ ES2015: export function execute(…)..

ตัวเลือกแรกอาจทำให้ยุ่งยากเล็กน้อยเพราะคอมไพเลอร์จะส่งออกไฟล์. js และคุณต้องเปลี่ยนเป็น. cjs ตลอดเวลา (เท่าที่ฉันรู้) ด้วยตัวเลือกที่สองคุณควรจะสามารถเรียกใช้ไฟล์ด้วยโหนด (รวมถึงแฟล็ก --experimental-modules สำหรับรุ่น <13.8)

หากคุณต้องการใช้ commonJS จริงๆอาจเป็นการดีกว่าที่จะติดตั้งนิยามชนิดสำหรับ Node: @ types / nodeและเปลี่ยนการอิมพอร์ตเป็นรูปแบบ commonJS: require('abc')และคงการตั้งค่าที่เหลือไว้เหมือนเดิม (แม้ว่าคุณสามารถเพิ่ม“ type” :“ commonjs” ถึง package.json เพื่อให้ชัดเจน)


1
ต้องการ ('abc') ไม่สามารถใช้คลาสในคำจำกัดความ. ts (เช่น: คลาส) ... เกี่ยวกับ. cjs extension ... ประเภทสามารถใช้ไฟล์. ts เท่านั้น ... ES2015 ไม่ใช่ตัวเลือกของฉันเพราะฉันใช้ โมดูลนี้ด้วยการนำเข้าเก่า (จำเป็น) ทุกที่ ... ฉันแก้ไขปัญหานี้ด้วยการใช้ JSDoc แต่ขอบคุณสำหรับคำตอบ
Zerumi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.