web-dev-qa-db-fra.com

Modules ES6: fonction onclick non définie après l'importation

Je teste des modules ES6 et je veux permettre à l'utilisateur d'accéder à certaines fonctions importées à l'aide de onclick:

test.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Module Test</title>
</head>
<body>
    <input type="button" value="click me" onclick="hello();"/>
    <script type="module">import {hello} from "./test.js";</script>
</body>
</html>

test.js:

export function hello() {console.log("hello");}

Lorsque je clique sur le bouton, la console du développeur indique: ReferenceError: hello is not defin . Comment puis-je importer des fonctions à partir de modules afin qu'elles soient disponibles en tant que fonctions onclick?

J'utilise Firefox 54.0 avec dom.moduleScripts.enabled défini sur true.

9
Konrad Höffner

Le module crée une portée pour éviter les conflits de noms. 

Soit exposer votre fonction à l'objet window

import {hello} from './test.js'

window.hello = hello

Ou utilisez addEventListener pour lier le gestionnaire. Démo

<button type="button" id="hello">Click Me</button>
<script type="module">
  import {hello} from './test.js'

  document.querySelector('#hello').addEventListener('click', hello)
</script>
22
Yury Tarabanko

Portée du module dans les modules ES6:

Lorsque vous importez un script de la manière suivante en utilisant type="module":

<script type="module">import {hello} from "./test.js";</script>

Vous créez une certaine étendue appelée portée de module. Voici où la portée des modules est relative aux autres niveaux de portée. Partant de global ils sont:

  1. Portée globale: toutes les déclarations en dehors d'un module du niveau le plus externe (c'est-à-dire pas dans une fonction, et pour const et let pas dans un bloc) sont accessibles de partout dans l'environnement d'exécution Javascript.
  2. Portée du module: toutes les déclarations à l'intérieur d'un module sont étendues au module. Lorsque d'autres javascipt tentent d'accéder à ces déclarations, une erreur de référence est générée.
  3. Portée de la fonction: toutes les variables déclarées à l'intérieur (au niveau supérieur) d'un corps de fonction sont étendues à une fonction
  4. Portée du bloc: les variables let et const ont une portée de bloc

Vous obteniez l'erreur referenceError car la fonction hello() a été déclarée dans le module, qui était module scoped . Comme nous l'avons vu précédemment, les déclarations à l'intérieur de la portée du module ne sont disponibles que dans ce module et vous avez essayé de l'utiliser en dehors du module. 

Nous pouvons faire des déclarations à l'intérieur d'un module global lorsque nous explicitement le mettons sur l'objet window afin que nous puissions l'utiliser en dehors du module. Par exemple:

window.hello = hello;  // putting the hello function as a property on the window object
1