Impor ES2015 tidak berfungsi (bahkan di tingkat atas) di Firefox

90

Ini adalah file contoh saya:

<!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");

Saat saya memuat halaman di Firefox 46, ia mengembalikan "SyntaxError: deklarasi impor hanya dapat muncul di tingkat atas modul" - tetapi saya tidak yakin berapa banyak lagi pernyataan impor tingkat atas yang bisa didapatkan di sini. Apakah kesalahan ini adalah red herring, dan apakah impor / ekspor belum didukung?

Christoph Burschka
sumber
2
Modul ES6 belum didukung di browser.
Felix Kling
2
Tidak benar Felix. Bahkan tidak di tahun 2016. Tidak didukung oleh 'Semua' browser akan lebih akurat.
Andrew S

Jawaban:

128

Sebenarnya kesalahan yang Anda dapatkan adalah karena Anda perlu menyatakan secara eksplisit bahwa Anda memuat modul - hanya penggunaan modul yang diizinkan:

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

Saya menemukannya di dokumen ini tentang menggunakan impor ES6 di browser . Bacaan yang direkomendasikan.

Sepenuhnya didukung di versi browser tersebut (dan yang lebih baru; daftar lengkap di caniuse.com ):

  • Firefox 60
  • Chrome (desktop) 65
  • Chrome (android) 66
  • Safari 1.1

Di browser lama Anda mungkin perlu mengaktifkan beberapa tanda di browser:

  • Chrome Canary 60 - di belakang bendera Platform Web Eksperimental di chrome:flags.
  • Firefox 54 - dom.moduleScripts.enabledpengaturan about:config.
  • Tepi 15 - di belakang pengaturan Fitur JavaScript Eksperimental di about:flags.
Tomáš Zato - Kembalikan Monica
sumber
1
Terima kasih; ini sepertinya informasi baru (bandingkan tabel dukungan browser jawaban sebelumnya dengan developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) jadi saya beralih ke jawaban Anda karena importtidak lagi tidak didukung.
Christoph Burschka
1
bekerja sekarang tanpa flag / pengaturan apa pun di edge 16299 dan chrome 64. Satu peringatan perlu mengimpor jalur, bukan file, jadi di t1.js: import Test from './t2.js';
Catweazle
@Catweazle Apakah Anda yakin itu './t2.js'dan bukan './t2'tanpa .js?
fredoverflow
@fredoverflow Ya, nama lengkap harus ditentukan, tidak seperti di Node.js.
Tomáš Zato - Kembalikan Monica
membutuhkan contoh lengkap, bukan hanya impor
bharal
14

Ini tidak akurat lagi. Semua browser saat ini sekarang mendukung modul ES6

Jawaban asli di bawah

Dari importMDN :

Fitur ini tidak diterapkan di browser mana pun secara native saat ini. Ini diterapkan di banyak transpiler, seperti Traceur Compiler, Babel atau Rollup.

Browser tidak mendukung import.

Berikut adalah tabel dukungan browser:

masukkan deskripsi gambar di sini

Jika Anda ingin mengimpor modul ES6, saya sarankan menggunakan transpiler (misalnya, babel ).

Josh Beam
sumber
Bisakah Anda mengaktifkan fitur ini menggunakan bendera (seperti di chrome)?
evolusionxbox
4
@evolutionxbox: Jika fitur tidak diimplementasikan , maka tidak ada tanda juga.
Bergi
1
Jika fitur tidak diimplementasikan, mengapa saya tidak mendapatkan kesalahan sintaks atau kesalahan yang memberi tahu saya bahwa fitur tersebut tidak diterapkan? Ini tidak masuk akal.
Tomáš Zato - Kembalikan Monica
@ TomášZato, hanya bergantung pada browser apa pun yang Anda gunakan memutuskan untuk menanganinya
Josh Beam
1
Sebenarnya, ada kesalahan dalam kode saya dan berfungsi dengan baik. Tidak yakin mengapa jawaban Anda diberi suara positif. Browser yang tidak mendukung impor melaporkannya. Kesalahan seperti yang dimaksud adalah kesalahan sebenarnya saat menggunakan impor.
Tomáš Zato - Kembalikan Monica
2

Hanya menggunakan ekstensi file .js saat mengimpor file menyelesaikan masalah yang sama (jangan lupa untuk menyetel type="moduledi tag skrip).

Cukup tulis:

import foo from 'foo.js';

dari pada

import foo from 'foo';
krmld
sumber
1

Tambahkan type=modulepada skrip yang mengimpor dan mengekspor modul akan menyelesaikan masalah ini.

Abhishek Khatri
sumber
0

Anda harus menentukan jenisnya dalam skrip dan ekspor harus default .. untuk contoh dalam kasus Anda seharusnya,

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

untuk t2.js gunakan default setelah ekspor seperti ini, ekspor default 'di sini ekspresi Anda pergi' (Anda tidak dapat menggunakan variabel di sini) . Anda dapat menggunakan fungsi seperti ini,

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

dan untuk impor, sintaks impor Anda harus seperti ini, impor cetak dari './t2.js' (gunakan ekstensi file dan ./ untuk direktori yang sama) .. Saya harap ini bermanfaat bagi Anda!

SK Biswas
sumber
0

Demi argumen ...

Seseorang dapat menambahkan antarmuka modul khusus ke objek jendela global. Meski, itu tidak disarankan. Di sisi lain, DOM sudah rusak dan tidak ada yang bertahan. Saya menggunakan ini sepanjang waktu untuk memuat silang modul dinamis dan berlangganan pendengar khusus. Ini mungkin bukan jawaban- tetapi berhasil. Stack overflow sekarang memiliki module.export yang memanggil peristiwa yang disebut 'Spork' - paling tidak hingga refresh ...

//  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
Paul Fabing
sumber