226
votes

"Uncaught SyntaxError: Impossible d'utiliser l'instruction d'importation en dehors d'un module" lors de l'importation d'ECMAScript 6

J'utilise ArcGIS JSAPI 4.12 et souhaite utiliser des illusions spatiales pour dessiner des symboles militaires sur une carte.

Lorsque j'ajoute milsymbol.js au script, la console renvoie une erreur

Uncaught SyntaxError: Impossible d'utiliser l'instruction d'importation en dehors d'un module`

donc j'ajoute type="module" au script, puis il retourne

Uncaught ReferenceError: ms n'est pas défini

Voici mon code:

import { ms } from "./ms.js";

import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;

export { ms };

Donc, que j'ajoute type="module" ou non, il y a toujours des erreurs. Cependant, dans le document officiel de Spatial Illusions, il n'y a pas de type="module" dans le script. Je suis maintenant vraiment confus. Comment parviennent-ils à le faire fonctionner sans ajouter le type?

Fichier milsymbol.js

<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>

<script>
    require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/MapImageLayer",
        "esri/layers/FeatureLayer"
    ], function (Map, MapView, MapImageLayer, FeatureLayer) {

        var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
        var map = new Map({
            basemap: "topo-vector"
        });

        var view = new MapView({
            container: "viewDiv",
            map: map,
            center: [121, 23],
            zoom: 7
        });
    });
</script>


2 commentaires

J'obtiens la même erreur en essayant d'importer un module! Avez-vous une solution?


J'utilise maintenant browserify grâce auquel je peux inclure n'importe quel module en utilisant require() . Regardez cette vidéo


10 Réponses :


96
votes

Il semble que la cause des erreurs soit:

  1. Vous chargez actuellement le fichier source dans le répertoire src au lieu du fichier construit dans le répertoire dist (vous pouvez voir quel est le fichier distribué prévu ici ). Cela signifie que vous utilisez le code source natif dans un état non modifié / dégroupé, ce qui entraîne l'erreur suivante: Uncaught SyntaxError: Cannot use import statement outside a module . Ce problème doit être résolu en utilisant la version fournie, car le package utilise un rollup pour créer un bundle.

  2. La raison pour laquelle vous obtenez l' Uncaught ReferenceError: ms is not defined est que les modules ont une portée, et puisque vous chargez la bibliothèque à l'aide de modules natifs, ms n'est pas dans la portée globale et n'est donc pas accessible dans la balise de script suivante .

Il semble que vous devriez pouvoir charger la version dist de ce fichier pour que ms défini dans la window . Consultez cet exemple de l'auteur de la bibliothèque pour voir un exemple de la façon dont cela peut être fait.


3 commentaires

Merci pour votre réponse, maintenant je sais que j'ai le mauvais fichier. J'ai cherché la version dist du fichier mais sans résultat. Connaissez-vous un moyen d'obtenir la version dist? Merci beaucoup!


Il est disponible en téléchargement sur npm ( npmjs.com/package/milsymbol ). Vous pouvez également le créer vous-même en clonant le dépôt et en exécutant l'un des scripts de génération. Il semble qu'il y ait un script de construction AMD ( github.com/spatialillusions/milsymbol/blob/master/… ) qui devrait vous permettre d' require le package intégré directement dans votre code.


J'ai téléchargé via npm, maintenant j'ai le script: <script src="node_modules/milsymbol/dist/milsymbol.js"></script> , mais la console renvoie toujours Uncaught ReferenceError: ms is not defined . Le problème est que ms n'est pas défini dans dist/milsymbol.js , il est défini dans src/milsymbol.js , mais il nécessite type="module" et causera un problème de portée. Existe-t-il une solution à ça. Merci beaucoup!



154
votes

J'ai eu cette erreur car j'ai oublié le type = "module" dans la balise de script:

<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>


0 commentaires

2
votes

L'erreur est déclenchée car le fichier auquel vous créez un lien dans votre fichier HTML est la version dégroupée du fichier. Pour obtenir la version complète, vous devrez l'installer avec npm :

npm install --save milsymbol

Cela télécharge le package complet dans votre dossier node_modules .

Vous pouvez ensuite accéder au fichier JavaScript node_modules/milsymbol/dist/milsymbol.js autonome à node_modules/milsymbol/dist/milsymbol.js

Vous pouvez le faire dans n'importe quel répertoire, puis copiez simplement le fichier ci-dessous dans votre répertoire /src .



22
votes

J'ai résolu ce problème en procédant comme suit:

Lorsque vous utilisez les modules ECMAScript 6 depuis le navigateur, utilisez l'extension .js dans vos fichiers et dans la balise script add type = "module" .

Lorsque vous utilisez des modules ECMAScript 6 à partir d'un environnement Node.js, utilisez l'extension .mjs dans vos fichiers et utilisez cette commande pour exécuter le fichier:

node --experimental-modules filename.mjs


1 commentaires

Modules: modules ECMAScript: activation de https://nodejs.org/api/esm.html#esm_enabling



0
votes

Ajoutez simplement .pack entre le nom et l'extension dans la <script> de src. c'est à dire:

<script src="name.pack.js">
// code here
</script>


0 commentaires

29
votes

J'étais également confronté au même problème jusqu'à ce que j'ajoute le type = "module" au script.

Avant c'était comme ça

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

Et après l'avoir changé en

<script src="../src/main.js"></script>

Cela a parfaitement fonctionné.


5 commentaires

Faire en sorte que CORS fasse cela


Cela signifie que vous faites une demande depuis un autre domaine. Vous pouvez résoudre ce problème en ajoutant Access-Control-Allow-Origin: * dans vos en-têtes. Vous pouvez consulter la documentation MDN sur CORS sur developer.mozilla.org/en-US/docs/Web/HTTP/… .


non je connais les cors, le truc c'est que ce sont mes fichiers locaux


Vous devez servir votre script dans un serveur http, les navigateurs utilisent une requête http pour charger les modules es6, le serveur doit répondre dans l'en-tête d'un CORS permettant votre origine.


le moyen le plus simple: vous pouvez utiliser le serveur http: stackoverflow.com/a/23122981/935330



12
votes

J'ai résolu mon cas en remplaçant «importer» par «exiger».

// import { parse } from 'node-html-parser';
parse = require('node-html-parser');


0 commentaires

11
votes

Je ne sais pas si cela est apparu ici comme une évidence. Je tiens à souligner qu'en ce qui concerne le JavaScript côté client (navigateur), vous pouvez ajouter type="module" aux scripts js externes et internes.

Disons que vous avez un fichier 'module.js':

import {a} from "module.js";     // this won't work

Vous pouvez l'utiliser dans un script externe, dans lequel vous effectuez l'importation, par exemple:

<!DOCTYPE html><html><body>
<script type="module">
    import {a} from "./module.js";
    alert(a);
</script>
</body></html>

test.js:

import {a} from "./module.js";
alert(a);

Vous pouvez également l'utiliser dans un script interne, par exemple:

<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>

Il est à noter que pour les chemins relatifs, vous ne devez pas omettre les caractères "./", c'est-à-dire:

var a = 10;
export {a};


0 commentaires

6
votes

Pour moi, cela a été causé avant que je ne renvoie une bibliothèque (spécifiquement typeORM , en utilisant le fichier ormconfig.js , sous la clé entities ) vers le dossier src , au lieu du dossier dist ...

   "entities": [
      "dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
   ],

au lieu de

   "entities": [
      "src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
   ],


2 commentaires

Pour moi, au moins, votre réponse n'est pas claire laquelle vous dites est la bonne façon


@claudekennilol - merci pour votre commentaire, j'ai modifié la réponse pour lever l'ambiguïté



3
votes

Mettre à jour pour le nœud / NPM

Ajoutez "type": "module" à votre package.json

{
  // ...
  "type": "module",
  // ...
}


0 commentaires