L'importazione di ES2015 non funziona (anche a livello superiore) in Firefox


94

Questi sono i miei file di esempio:

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

Quando carico la pagina in Firefox 46, restituisce "SyntaxError: le dichiarazioni di importazione possono apparire solo al livello più alto di un modulo" - ma non sono sicuro di quanto più alto livello possa ottenere l'istruzione import qui. Questo errore è una falsa pista e l'importazione / esportazione non è ancora supportata?


2
I moduli ES6 non sono ancora supportati nei browser.
— Felix Kling

2
Non è vero Felix. Nemmeno nel 2016. Non supportato da "Tutti" i browser sarebbe più accurato.
— Andrew S

Risposte:


133

In realtà l'errore che hai ricevuto è stato perché devi dichiarare esplicitamente che stai caricando un modulo - solo allora l'uso dei moduli è consentito:

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

L'ho trovato in questo documento sull'utilizzo dell'importazione ES6 nel browser . Lettura consigliata.

Completamente supportato in quelle versioni del browser (e successive; elenco completo su caniuse.com ):

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

Nei browser meno recenti potrebbe essere necessario abilitare alcuni flag nei browser:

  • Chrome Canary 60 - dietro il flag della piattaforma web sperimentale in chrome:flags .
  • Firefox 54 - dom.moduleScripts.enabled impostazione in about:config.
  • Edge 15: dietro l'impostazione delle funzionalità JavaScript sperimentali in about:flags.

1
Grazie; questa sembra essere una nuova informazione (confronta la tabella di supporto del browser della risposta precedente con developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) quindi passo alla tua risposta perché importnon è più supportata.
— Christoph Burschka,

1
funziona ora senza flag / impostazioni in edge 16299 e chrome 64. Un avvertimento è necessario importare il percorso, non il file, quindi in t1.js: import Test from './t2.js';
— Catweazle

@Catweazle Sei sicuro che sia './t2.js'e non './t2'senza il .js?
— fredoverflow

@fredoverflow Sì, è necessario specificare il nome completo, a differenza di Node.js.
— Tomáš Zato - Ripristina Monica

ha bisogno di un esempio completo, non solo dell'importazione
— bharal

14

Questo non è più accurato. Tutti i browser attuali ora supportano i moduli ES6

Risposta originale di seguito

Da importsu MDN :

Questa funzione non è implementata in alcun browser in modo nativo in questo momento. È implementato in molti transpiler, come Traceur Compiler, Babel o Rollup.

I browser non supportano import.

Ecco la tabella di supporto del browser:

inserisci qui la descrizione dell'immagine

Se vuoi importare moduli ES6, ti suggerirei di utilizzare un transpiler (ad esempio, babel ).


Puoi attivare queste funzionalità utilizzando un flag (come in Chrome)?
— evolutionxbox

4
@evolutionxbox: se le funzionalità non sono impelementate , non c'è nemmeno una bandiera.
— Bergi

1
Se le funzionalità non sono implementate, perché non ricevo un errore di sintassi o un errore che mi dice che non sono implementate? Questo non ha senso.
— Tomáš Zato - Ripristina Monica il

@ TomášZato, dipende solo dal browser che stai utilizzando ha deciso di gestirlo
— Josh Beam,

1
In realtà, c'è stato un errore nel mio codice e funziona perfettamente. Non sono sicuro del motivo per cui la tua risposta è stata votata. I browser che non supportano le importazioni lo segnalano. Errori come quello in questione sono errori effettivi che utilizzano le importazioni.
— Tomáš Zato - Ripristina Monica il

2

Il semplice utilizzo dell'estensione file .js durante l'importazione dei file ha risolto lo stesso problema (non dimenticare di impostare type="modulenel tag script).

Scrivi semplicemente:

import foo from 'foo.js';

invece di

import foo from 'foo';

1

Aggiungere type=modulegli script che importano ed esportano i moduli risolverebbe questo problema.


0

devi specificare il suo tipo di script e l'esportazione deve essere predefinita ..per ex nel tuo caso dovrebbe essere,

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

per t2.js usa default dopo l'esportazione in questo modo, esporta default 'qui va la tua espressione' (non puoi usare la variabile qui) . puoi usare funzioni come questa,

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

e per l'importazione, la tua sintassi di importazione dovrebbe essere così, import print da './t2.js' (usa l'estensione file e ./ per la stessa directory) .. Spero che questo ti sia utile!


0

Per amor di discussione ...

Si potrebbe aggiungere un'interfaccia del modulo personalizzato all'oggetto finestra globale. Anche se non è consigliato. D'altra parte, il DOM è già rotto e nulla persiste. Lo uso sempre per eseguire il caricamento incrociato di moduli dinamici e sottoscrivere listener personalizzati. Questa probabilmente non è una risposta, ma funziona. Stack overflow ora ha un module.export che chiama un evento chiamato 'Spork' - almeno fino all'aggiornamento ...

//  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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.