La importación de ES2015 no funciona (incluso en el nivel superior) en Firefox

90

Estos son mis archivos de muestra:

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

Cuando cargo la página en Firefox 46, devuelve "SyntaxError: las declaraciones de importación solo pueden aparecer en el nivel superior de un módulo", pero no estoy seguro de cuánto más nivel superior puede obtener la declaración de importación aquí. ¿Es este error una pista falsa y la importación / exportación simplemente no es compatible todavía?

Christoph Burschka
fuente
2
Los módulos ES6 aún no son compatibles con los navegadores.
Felix Kling
2
No es cierto Felix. Ni siquiera en 2016. No admitido por "Todos" los navegadores serían más precisos.
Andrew S

Respuestas:

128

En realidad, el error que obtuvo fue porque necesita indicar explícitamente que está cargando un módulo, solo entonces se permite el uso de módulos:

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

Lo encontré en este documento sobre el uso de la importación de ES6 en el navegador . Lectura recomendada.

Totalmente compatible con esas versiones del navegador (y posteriores; lista completa en caniuse.com ):

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

En navegadores más antiguos, es posible que deba habilitar algunas banderas en los navegadores:

  • Chrome Canary 60: detrás de la bandera de la plataforma web experimental en chrome:flags.
  • Firefox 54: dom.moduleScripts.enabledinstalación about:config.
  • Edge 15: detrás de la configuración de características experimentales de JavaScript en about:flags.
Tomáš Zato - Reincorporar a Monica
fuente
1
Gracias; esto parece ser información nueva (compare la tabla de soporte del navegador de la respuesta anterior con developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) así que voy a cambiar a su respuesta importya que ya no es compatible.
Christoph Burschka
1
trabajando ahora sin ningún indicador / configuración en el borde 16299 y Chrome 64. Una advertencia es necesario importar la ruta, no el archivo, por lo que en t1.js: import Test from './t2.js';
Catweazle
@Catweazle ¿Estás seguro de que es './t2.js'y no './t2'sin el .js?
fredoverflow
@fredoverflow Sí, se debe especificar el nombre completo, a diferencia de Node.js.
Tomáš Zato - Reincorpora a Monica
necesita un ejemplo completo, no solo la importación
bharal
14

Esto ya no es exacto. Todos los navegadores actuales ahora admiten módulos ES6

Respuesta original a continuación

Desde importMDN :

Esta función no está implementada en ningún navegador de forma nativa en este momento. Se implementa en muchos transpilers, como Traceur Compiler, Babel o Rollup.

Los navegadores no admiten import.

Aquí está la tabla de soporte del navegador:

ingrese la descripción de la imagen aquí

Si desea importar módulos ES6, le sugiero que use un transpilador (por ejemplo, babel ).

Josh Beam
fuente
¿Puede activar estas funciones con una bandera (como en Chrome)?
evolutionxbox
4
@evolutionxbox: si las funciones no están impelementadas , tampoco hay bandera.
Bergi
1
Si las funciones no están implementadas, ¿por qué no obtengo un error de sintaxis o un error que me dice que no están implementadas? Esto no tiene sentido.
Tomáš Zato - Reincorporación a Monica
@ TomášZato, solo depende de cualquier navegador que esté usando decidió manejarlo
Josh Beam
1
En realidad, hubo un error en mi código y funciona bien. No estoy seguro de por qué su respuesta fue votada a favor. Los navegadores que no admiten importaciones lo informan. Errores como el en cuestión son errores reales al utilizar importaciones.
Tomáš Zato - Reincorpora a Monica
2

El solo uso de la extensión de archivo .js al importar archivos resolvió el mismo problema (no olvide configurar la type="moduleetiqueta de script).

Simplemente escribe:

import foo from 'foo.js';

en vez de

import foo from 'foo';
krmld
fuente
1

Agregar type=modulelos scripts que importan y exportan los módulos resolvería este problema.

Abhishek Khatri
fuente
0

debe especificar su tipo en el script y exportar debe ser predeterminado ... por ejemplo, en su caso, debería serlo,

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

para t2.js, use el valor predeterminado después de exportar de esta manera, exporte el valor predeterminado 'aquí va su expresión' (no puede usar la variable aquí) . puedes usar una función como esta,

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

y para la importación, su sintaxis de importación debería ser así, importar impresión desde './t2.js' (use la extensión de archivo y ./ para el mismo directorio). ¡ Espero que esto le sea útil!

SK Biswas
fuente
0

Por el valor del argumento...

Se podría agregar una interfaz de módulo personalizado al objeto de ventana global. Aunque no se recomienda. Por otro lado, el DOM ya está roto y no persiste nada. Utilizo esto todo el tiempo para cruzar módulos dinámicos de carga y suscribir oyentes personalizados. Probablemente no sea una respuesta, pero funciona. Stack overflow ahora tiene un module.export que llama a un evento llamado 'Spork', al menos hasta que se actualice ...

//  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
fuente