L'importation ES2015 ne fonctionne pas (même au plus haut niveau) dans Firefox

90

Voici mes exemples de fichiers:

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

Lorsque je charge la page dans Firefox 46, elle renvoie "SyntaxError: les déclarations d'importation peuvent n'apparaître qu'au niveau supérieur d'un module" - mais je ne suis pas sûr du niveau supérieur que l'instruction d'importation peut obtenir ici. Cette erreur est-elle un hareng rouge et l'importation / exportation n'est-elle tout simplement pas encore prise en charge?

Christoph Burschka
la source
2
Les modules ES6 ne sont pas encore pris en charge dans les navigateurs.
Felix Kling le
2
Pas vrai Felix. Pas même en 2016. Non pris en charge par les navigateurs «Tous» serait plus précis.
Andrew S

Réponses:

128

En fait, l'erreur que vous avez obtenue est que vous devez indiquer explicitement que vous chargez un module - alors seulement l'utilisation de modules est autorisée:

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

Je l'ai trouvé dans ce document sur l'utilisation de l'importation ES6 dans le navigateur . Lecture recommandée.

Entièrement pris en charge dans ces versions de navigateur (et versions ultérieures; liste complète sur caniuse.com ):

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

Dans les navigateurs plus anciens, vous devrez peut-être activer certains indicateurs dans les navigateurs:

  • Chrome Canary 60 - derrière l'indicateur de la plateforme Web expérimentale dans chrome:flags.
  • Firefox 54 - dom.moduleScripts.enabledinstallation about:config.
  • Edge 15 - derrière le paramètre Fonctionnalités JavaScript expérimentales dans about:flags.
Tomáš Zato - Réintégrer Monica
la source
1
Merci; cela semble être de nouvelles informations (comparez le tableau de prise en charge du navigateur de la réponse précédente avec developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) donc je passe à votre réponse car elle importn'est plus non prise en charge.
Christoph Burschka
1
fonctionne maintenant sans aucun indicateur / paramètre dans le bord 16299 et le chrome 64. Une mise en garde nécessite d'importer le chemin, pas le fichier, donc dans t1.js: import Test from './t2.js';
Catweazle
@Catweazle Êtes-vous sûr que ce n'est './t2.js'pas './t2'sans le .js?
fredoverflow
@fredoverflow Oui, le nom complet doit être spécifié, contrairement à Node.js.
Tomáš Zato - Réintégrer Monica
a besoin d'un exemple complet, pas seulement l'importation
bharal
14

Ce n'est plus exact. Tous les navigateurs actuels prennent désormais en charge les modules ES6

Réponse originale ci-dessous

À partir importde MDN :

Cette fonctionnalité n'est actuellement implémentée dans aucun navigateur de manière native. Il est implémenté dans de nombreux transpileurs, tels que Traceur Compiler, Babel ou Rollup.

Les navigateurs ne prennent pas en charge import.

Voici le tableau de prise en charge du navigateur:

entrez la description de l'image ici

Si vous souhaitez importer des modules ES6, je vous suggère d'utiliser un transpilateur (par exemple, babel ).

Josh Beam
la source
Pouvez-vous activer ces fonctionnalités en utilisant un indicateur (comme dans Chrome)?
evolutionxbox
4
@evolutionxbox: Si les fonctionnalités ne sont pas implémentées , alors il n'y a pas non plus de drapeau.
Bergi
1
Si les fonctionnalités ne sont pas implémentées, pourquoi ne reçois-je pas une erreur de syntaxe ou une erreur m'indiquant qu'elles ne sont pas implémentées? Cela n'a aucun sens.
Tomáš Zato - Réintégrer Monica le
@ TomášZato, cela dépend de la façon dont le navigateur que vous utilisez a décidé de le gérer
Josh Beam
1
En fait, il y avait une erreur dans mon code et cela fonctionne très bien. Je ne sais pas pourquoi votre réponse a été votée. Les navigateurs qui ne prennent pas en charge les importations le signalent. Les erreurs comme celle en question sont des erreurs réelles lors des importations.
Tomáš Zato - Réintégrer Monica le
2

Le simple fait d'utiliser l'extension de fichier .js lors de l'importation de fichiers a résolu le même problème (n'oubliez pas de définir type="module balise script).

Écrivez simplement:

import foo from 'foo.js';

au lieu de

import foo from 'foo';
krmld
la source
1

Ajouter type=moduleles scripts qui importent et exportent les modules résoudrait ce problème.

Abhishek Khatri
la source
0

vous devez spécifier son type dans le script et l'exportation doit être par défaut .. par exemple dans votre cas, il devrait être,

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

pour t2.js, utilisez la valeur par défaut après l'exportation comme celle-ci, exportez la valeur par défaut «ici votre expression va» (vous ne pouvez pas utiliser de variable ici) . vous pouvez utiliser une fonction comme celle-ci,

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

et pour l'importation, votre syntaxe d'importation devrait être comme ceci, importez l'impression depuis './t2.js' (utilisez l'extension de fichier et ./ pour le même répertoire) .. J'espère que cela vous sera utile!

SK Biswas
la source
0

Pour le bien de l'argument...

On pourrait ajouter une interface de module personnalisée à l'objet de fenêtre globale. Bien que cela ne soit pas recommandé. En revanche, le DOM est déjà cassé et rien ne persiste. J'utilise cela tout le temps pour charger des modules dynamiques et souscrire des écouteurs personnalisés. Ce n'est probablement pas une réponse, mais cela fonctionne. Le débordement de pile a maintenant un module.export qui appelle un événement appelé 'Spork' - au moins jusqu'à l'actualisation ...

//  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
la source