การนำเข้า ES2015 ไม่ทำงาน (แม้ในระดับบนสุด) ใน Firefox


92

นี่คือไฟล์ตัวอย่างของฉัน:

<!DOCTYPE html>
<html>
<head>
  <title>Test</title>
  <script src="t1.js"></script>
</head>
<body></body>
</html>

t1.js:

import Test from 't2.js';

t2.js:

export const Test = console.log("Hello world");

เมื่อฉันโหลดหน้าใน Firefox 46 มันจะส่งคืน "SyntaxError: การประกาศการนำเข้าอาจปรากฏที่ระดับบนสุดของโมดูลเท่านั้น" - แต่ฉันไม่แน่ใจว่าคำสั่งนำเข้าระดับบนสุดสามารถรับที่นี่ได้มากเพียงใด ข้อผิดพลาดนี้เป็นปลาเฮอริ่งแดงและยังไม่รองรับการนำเข้า / ส่งออกใช่หรือไม่


2
ยังไม่รองรับโมดูล ES6 ในเบราว์เซอร์
Felix Kling

2
ไม่ใช่เฟลิกซ์ที่แท้จริง แม้แต่ในปี 2016 เบราว์เซอร์ "ทั้งหมด" ไม่รองรับจะมีความแม่นยำมากกว่า
Andrew S

คำตอบ:


131

จริงๆแล้วข้อผิดพลาดที่คุณได้รับเป็นเพราะคุณต้องระบุอย่างชัดเจนว่าคุณกำลังโหลดโมดูล - อนุญาตให้ใช้โมดูลเท่านั้น:

<script src="t1.js" type="module"></script>

ฉันพบในเอกสารฉบับนี้เกี่ยวกับการใช้การนำเข้า ES6 ในเบราว์เซอร์ แนะนำให้อ่าน

ได้รับการสนับสนุนอย่างเต็มที่ในเวอร์ชันเบราว์เซอร์เหล่านั้น (และใหม่กว่ารายการทั้งหมดในcaniuse.com )

  • Firefox 60
  • Chrome (เดสก์ท็อป) 65
  • Chrome (Android) 66
  • Safari 1.1

ในเบราว์เซอร์รุ่นเก่าคุณอาจต้องเปิดใช้แฟล็กในเบราว์เซอร์:

  • Chrome Canary 60 - อยู่เบื้องหลังการตั้งค่าสถานะ Experimental Web Platform ในchrome:flags.
  • Firefox 54 - dom.moduleScripts.enabledการตั้งค่าในabout:config.
  • Edge 15 - เบื้องหลังการตั้งค่าคุณลักษณะ JavaScript แบบทดลองในabout:flags.

1
ขอบคุณ; ดูเหมือนจะเป็นข้อมูลใหม่ (เปรียบเทียบตารางการสนับสนุนเบราว์เซอร์ของคำตอบก่อนหน้ากับdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) ดังนั้นฉันจึงเปลี่ยนไปใช้คำตอบของคุณเนื่องจากimportไม่ได้รับการสนับสนุนอีกต่อไป
Christoph Burschka

1
ทำงานได้ทันทีโดยไม่มีแฟล็ก / การตั้งค่าใด ๆ ใน edge 16299 และ chrome 64 ข้อแม้อย่างหนึ่งต้องนำเข้าเส้นทางไม่ใช่ไฟล์ดังนั้นใน t1.js: import Test from './t2.js';
Catweazle

@Catweazle คุณแน่ใจหรือ'./t2.js'ไม่ว่า'./t2'ไม่มี.js?
fredoverflow

@fredoverflow ใช่ต้องระบุชื่อเต็มไม่เหมือนกับใน Node.js
Tomáš Zato - คืนสถานะ Monica

ต้องการตัวอย่างที่สมบูรณ์ไม่ใช่แค่การนำเข้า
bharal

14

สิ่งนี้ไม่ถูกต้องอีกต่อไป ตอนนี้เบราว์เซอร์ปัจจุบันทั้งหมดรองรับโมดูล ES6 แล้ว

คำตอบเดิมด้านล่าง

จากimportบน MDN :

คุณลักษณะนี้ไม่ได้ใช้งานในเบราว์เซอร์ใด ๆ ในขณะนี้ มีการนำไปใช้ในทรานส์ไพเลอร์หลายตัวเช่น Traceur Compiler, Babel หรือ Rollup

importเบราว์เซอร์ไม่สนับสนุน

ตารางรองรับเบราว์เซอร์มีดังนี้

ป้อนคำอธิบายภาพที่นี่

หากคุณต้องการนำเข้าโมดูล ES6 ฉันขอแนะนำให้ใช้ทรานสไพเลอร์ (ตัวอย่างเช่นบาเบล )


คุณสามารถเปิดคุณลักษณะเหล่านี้โดยใช้แฟล็ก (เช่นใน Chrome) ได้หรือไม่
evolutionxbox

4
@evolutionxbox: หากคุณสมบัติไม่จำเป็นก็จะไม่มีการตั้งค่าสถานะเช่นกัน
Bergi

1
หากไม่มีการนำคุณสมบัติไปใช้ทำไมฉันจึงไม่ได้รับข้อผิดพลาดทางไวยากรณ์หรือข้อผิดพลาดที่แจ้งว่าไม่มีการใช้งาน สิ่งนี้ไม่สมเหตุสมผล
Tomáš Zato - คืนสถานะ Monica

@ TomášZatoขึ้นอยู่กับว่าคุณใช้เบราว์เซอร์ใดก็ตามที่ตัดสินใจจัดการ
Josh Beam

1
อันที่จริงมีข้อผิดพลาดในรหัสของฉันและใช้งานได้ดี ไม่แน่ใจว่าทำไมคำตอบของคุณถึงได้รับการโหวต เบราว์เซอร์ที่ไม่รองรับการนำเข้าจะรายงาน ข้อผิดพลาดเช่นเดียวกับที่เป็นปัญหาคือข้อผิดพลาดที่เกิดขึ้นจริงจากการนำเข้า
Tomáš Zato - คืนสถานะ Monica

2

เพียงใช้นามสกุลไฟล์. js ในขณะที่นำเข้าไฟล์ก็สามารถแก้ปัญหาเดียวกันได้แล้ว (อย่าลืมตั้งค่าtype="moduleในแท็กสคริปต์)

เพียงเขียน:

import foo from 'foo.js';

แทน

import foo from 'foo';

1

เพิ่มtype=moduleสคริปต์ที่อิมพอร์ตและเอ็กซ์พอร์ตโมดูลจะแก้ปัญหานี้ได้


0

คุณต้องระบุว่าเป็นประเภทของสคริปต์และการส่งออกจะต้องเป็นค่าเริ่มต้น .. สำหรับกรณีของคุณควรเป็น

<script src='t1.js' type='module'>

สำหรับ t2.js ใช้ค่าเริ่มต้นหลังจากที่การส่งออกเช่นนี้ การส่งออกเริ่มต้นที่นี่การแสดงออกของคุณไป '(คุณไม่สามารถใช้ตัวแปรที่นี่) คุณสามารถใช้ฟังก์ชันเช่นนี้

export default function print(){ return console.log('hello world');}

และสำหรับการนำเข้าไวยากรณ์การนำเข้าของคุณควรเป็นเช่นนี้ให้ นำเข้าพิมพ์จาก "./t2.js" (ใช้นามสกุลไฟล์และ. / สำหรับไดเร็กทอรีเดียวกัน) .. ฉันหวังว่านี่จะเป็นประโยชน์กับคุณ!


0

เพื่อประโยชน์ในการโต้แย้ง ...

หนึ่งสามารถเพิ่มอินเทอร์เฟซโมดูลที่กำหนดเองให้กับวัตถุหน้าต่างส่วนกลาง แม้ว่าจะไม่แนะนำ ในทางกลับกัน DOM เสียไปแล้วและไม่มีอะไรคงอยู่ ฉันใช้สิ่งนี้ตลอดเวลาเพื่อโหลดโมดูลไดนามิกข้ามและสมัครสมาชิกฟังแบบกำหนดเอง นี่อาจไม่ใช่คำตอบ แต่ได้ผล ตอนนี้ Stack overflow มี module.export ที่เรียกเหตุการณ์ที่เรียกว่า 'Spork' - เกรงว่าจะรีเฟรช ...

//  spam the global window with a custom method with a private get/set-interface and     error handler... 

window.modules = function(){
  window.exports = {
    get(modName) {
      return window.exports[modName] ? window.exports[modName] : new Error(`ERRMODGLOBALNOTFOUND [${modName}]`)
    },
    set(type, modDeclaration){
      window.exports[type] = window.exports[type] || []
      window.exports[type].push(modDeclaration)

    }
  }

}

//  Call the method
window.modules()

//  assign a custom type and function
window.exports.set('Spork', () => console.log('SporkSporSpork!!!'))


// Give your export a ridiculous event subscription chain type...
const foofaalala = window.exports.get('Spork')

// Iterate and call (for a mock-event chain)
foofaalala.forEach(m => m.apply(this))

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