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.