【问题标题】:"Uncaught SyntaxError: Cannot use import statement outside a module" when importing ECMAScript 6\"Uncaught SyntaxError: Cannot use import statement outside a module\" 导入 ECMAScript 6 时
【发布时间】:2022-11-21 01:44:06
【问题描述】:

我正在使用 ArcGIS JSAPI 4.12 并希望使用 Spatial Illusions 在地图上绘制军事符号。

当我在脚本中添加 milsymbol.js 时,控制台返回错误

未捕获的语法错误:无法在模块外使用导入语句`

所以我在脚本中添加type="module",然后它返回

未捕获的 ReferenceError:未定义 ms

这是我的代码:

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

所以,不管我加不加type="module",总是报错。但是,在Spatial Illusions的官方文档中,脚本中并没有type="module"。我现在真的很困惑。他们如何在不添加类型的情况下设法让它工作?

文件米尔符号.js

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

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

export { ms };

【问题讨论】:

  • 我在尝试导入模块时遇到了同样的错误!你有什么解决办法吗?
  • 我现在正在使用 browserify,通过它我可以使用 require() 包含任何模块。看看这个video
  • view rate而言,这个问题在 Stack Overflow 上所有21,642,537 questions 中排名前 10(大概来自搜索引擎命中)。在其生命周期内,每天的浏览量约为 1800 次。
  • npm install node-fetch@2.0 例如,因为为什么 TF 使用 3.0 版本破坏了 API。永远不要破坏模块化组件的 API,扩展它,或者什么都不做, 谢谢。

标签: javascript ecmascript-6 arcgis arcgis-js-api


【解决方案1】:

我收到此错误是因为我忘记了脚本标签内的 type="module"

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

【讨论】:

    【解决方案2】:

    Node.js / NPM 更新

    "type": "module" 添加到您的 package.json 文件。

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

    笔记: 使用模块时,如果你得到ReferenceError: require is not defined,你需要使用import syntax而不是require。你不能在它们之间混合搭配,所以你需要选择一个或use a bundler if you need to use both

    【讨论】:

    • 是的。基本上,不要独立运行 TypeScript 脚本,而是将它们放在现有的 Angular 项目中,一切都会正常进行;-)
    • @wormsparty Escape the loop
    • 添加 "type": "module" 对我有用!
    【解决方案3】:

    看起来错误的原因是:

    1. 您当前正在加载 src 目录中的源文件,而不是 dist 目录中的构建文件(您可以看到预期的分发文件是 here)。这意味着您在未更改/未捆绑状态下使用本机源代码,导致以下错误:Uncaught SyntaxError: Cannot use import statement outside a module。这应该通过使用捆绑版本来解决,因为包是 using rollup 来创建一个包。

    2. 您收到 Uncaught ReferenceError: ms is not defined 错误的原因是因为模块是作用域的,并且由于您使用本机模块加载库,ms 不在全局范围内,因此无法在以下脚本标记中访问。

      看起来您应该能够加载此文件的 dist 版本以在 window 上定义 ms。查看库作者的 this example 以查看如何完成此操作的示例。

    【讨论】:

    • 谢谢你的回复,现在我知道我有错误的文件。我一直在寻找文件的 dist 版本,但没有结果。你知道有什么方法可以得到 dist 版本吗?非常感谢!
    • 它可以在 npm (npmjs.com/package/milsymbol) 上下载。或者,您可以通过克隆存储库并运行其中一个构建脚本来自己构建它。看起来有一个 AMD 构建脚本 (github.com/spatialillusions/milsymbol/blob/master/…) 应该允许您将构建的包直接require 到您的代码中。
    • 我已经通过 npm 下载,现在我有脚本:&lt;script src="node_modules/milsymbol/dist/milsymbol.js"&gt;&lt;/script&gt;,但控制台仍然返回 Uncaught ReferenceError: ms is not defined。问题是 ms 没有在 dist/milsymbol.js 中定义,它在 src/milsymbol.js 中定义,但它需要 type="module" 并且会导致范围问题。有什么解决办法吗?非常感谢!
    • 如果那是实际意图怎么办,从 /src 引用它。例如,由于作者不打算公开某个类的属性......
    【解决方案4】:

    我通过用“require”替换“import”解决了我的问题。

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

    【讨论】:

    • 谢谢,我也用这种语法解决了我的问题
    • const {parse} = require('node-html-parser'); 为我工作
    • 解释是什么?为什么这行得通?请通过 editing (changing) your answer 回复,而不是在 cmets 中回复(没有“编辑:”、“更新:”或类似的 - 答案应该看起来就像是今天写的一样)。
    • 问题是关于浏览器的
    • 如果您想保持老派,这个答案在 NodeJs 中很有用。但这与问题无关
    【解决方案5】:

    在将 type="module" 添加到脚本之前,我也遇到了同样的问题。

    以前是这样的

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

    并将其更改为

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

    它工作得很好。

    【讨论】:

    • 让 CORS 这样做
    • 这意味着您正在从另一个域请求。您可以通过在标头中添加 Access-Control-Allow-Origin: * 来解决此问题。您可以在 developer.mozilla.org/en-US/docs/Web/HTTP/… 查看关于 CORS 的 MDN 文档。
    • 不,我不知道 cors ,问题是这些是我的本地文件
    • 您需要在 http 服务器中提供您的脚本,浏览器使用 http 请求来加载 es6 模块,服务器需要在标头中响应一个允许您的来源的 CORS。
    • 最简单的方法:你可以使用 http-server: stackoverflow.com/a/23122981/935330
    【解决方案6】:

    我通过执行以下操作解决了这个问题:

    从浏览器使用 ECMAScript 6 模块时,请在文件中使用 .js 扩展名,并在脚本标记中添加 type = "module"

    在 Node.js 环境中使用 ECMAScript 6 模块时,请在文件中使用扩展名 .mjs 并使用此命令运行文件:

    node --experimental-modules filename.mjs
    

    编辑:这是在 node12 是最新的 LTS 时编写的,这不适用于节点 14 LTS。

    【讨论】:

    • 模块:ECMAScript 模块:启用https://nodejs.org/api/esm.html#esm_enabling
    • 这不再是必要的。只需将 "type": "module" 添加到您的 package.json 中,一切都会按预期工作。 (使用 .js 作为文件扩展名)
    • 我们也可以使用.cjs 文件。
    【解决方案7】:

    解决这个问题的方法有以下三种:

    1. 第一种:在脚本中,包含type=module

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

    2. 第二个:在 node.js 中,进入你的 package.json 文件

        {
           
            "type": "module",
           
        }
    

    3、第三种:用required代替import

    Try this

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

    Else try this

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

    【讨论】:

    • 如果所有 3 个都不起作用怎么办?我想要一个简单的 api.js 文件,其中包含大量我不想一次导入一个的可重用全局函数。即:<script id="apijs" src="%PUBLIC_URL%/api.js"></script>
    • 这3种方式是AND还是OR。以及如何在 NextJS 中使用这些。
    【解决方案8】:

    我不知道这在这里是否很明显。我想指出,就客户端(浏览器)JavaScript 而言,您可以将 type="module" 添加到外部和内部 js 脚本。

    比如说,你有一个文件“module.js”:

    var a = 10;
    export {a};
    

    您可以在执行导入的外部脚本中使用它,例如:

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

    测试.js:

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

    您也可以在内部脚本中使用它,例如:

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

    值得一提的是,对于相对路径,一定不能省略“./”字符,即:

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

    【讨论】:

      【解决方案9】:

      对我来说,这是由于没有将库(特别是typeORM,使用ormconfig.js文件,在entities键下)引用到src文件夹,而不是dist文件夹...

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

      代替

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

      【讨论】:

        【解决方案10】:

        如果要对模块使用 import 而不是 require() ,请在 package.json 文件中将 type 的值更改或添加到 module

        例子:

        package.json 文件

        {
          "name": "appsample",
          "version": "1.0.0",
          "type": "module",
          "description": "Learning Node",
          "main": "app.js",
          "scripts": {
            "test": "echo "Error: no test specified" && exit 1"
          },
          "author": "Chikeluba Anusionwu",
          "license": "ISC"
        }
        
        import http from 'http';
        
        var host = '127.0.0.1',
            port = 1992,
            server = http.createServer();
        
        server.on('request', (req, res) => {
          res.writeHead(200, {"Content-Type": "text/plain"});
          res.end("I am using type module in package.json file in this application.");
        });
        
        server.listen(port, () => console.log(
            'Listening to server ${port}. Connection has been established.'));
        

        【讨论】:

        • 这解决了我的问题。
        • 伟大的!我很高兴它做到了。
        【解决方案11】:

        我在 React 中收到此错误,并通过以下步骤修复了它:

        1. 前往项目根目录,并打开包.json文件进行编辑。

        2. 添加"type":"module";

        3. 保存并重启服务器。

        【讨论】:

          【解决方案12】:

          添加 "type": "module", 到你的包.json文件。

          并重新启动您的应用程序:

          npm start

          那么你的问题就解决了。

          【讨论】:

          • 逗号是不是它的一部分?
          • @PeterMortensen 你正在向 JSON 对象添加一个项目,项目用逗号分隔,所以除非你在末尾添加它,否则你需要一个逗号。
          • 但我不是在写模块?
          【解决方案13】:

          我正在使用 vanilla JavaScript 进行编码。如果您这样做,只需将 type="module" 添加到您的脚本标签。

          也就是之前的代码:

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

          更新代码:

          <script type="module" src="./index.js"></script>`
          

          【讨论】:

          【解决方案14】:

          为什么会发生这种情况以及更多可能的原因:

          很多接口仍然不理解ES6 JavaScript 语法/特性。因此,无论何时在任何文件或项目中使用 ES6,都需要将其编译为 ES5

          SyntaxError: Cannot use import statement outside a module 错误的可能原因是您试图独立运行该文件。您尚未安装和设置 ES6 编译器,例如 Babel,或者运行脚本中的文件路径错误/不是编译文件。

          如果你想在没有编译器的情况下继续,最好的解决方案是使用 ES5 语法,在你的情况下是 var ms = require(./ms.js);。这可以在以后根据需要进行更新,或者更好地设置你的编译器并确保你的文件/项目在运行之前被编译,并且确保你的运行脚本正在运行通常命名为 dist,build 或任何你命名的编译文件以及到运行脚本中的编译文件是正确的。

          【讨论】:

          • 谢谢你。这是试图找出根本原因的仅有的两个答案之一。我希望 Node.js 15.5 支持这个 2016 功能,但我发现它不支持?
          • @goldfishalpha?
          【解决方案15】:

          对我来说,这有帮助:

          1. 在我使用的.ts文件中:import prompts from "prompts";
          2. 并在文件中使用"module": "commonjs"tsconfig.json文件

          【讨论】:

          • 什么.ts文件是什么?
          • 它是您的代码需要添加一些模块导入的任何 typeScript 或 JavaScript 文件。
          【解决方案16】:

          触发错误是因为您在 HTML 文件中链接到的文件是该文件的未捆绑版本。 要获得完整的捆绑版本,您必须使用 npm 安装它:

          npm install --save milsymbol
          

          这会将完整包下载到您的node_modules 文件夹。

          然后,您可以在node_modules/milsymbol/dist/milsymbol.js 访问独立的缩小 JavaScript 文件

          您可以在任何目录中执行此操作,然后只需将以下文件复制到您的/src 目录即可。

          【解决方案17】:

          使用此代码。它对我很有效:

          将此脚本标记添加到文件索引.html:

          <script type="module">
              import { ms } from "./ms.js";
              import Symbol from "./ms/symbol.js";
          </script>
          

          【讨论】:

          【解决方案18】:

          我在 EXPO 遇到了同样的错误。

          主要解决方法是在package.json文件中添加"type": "module",

          但是,您必须检查哪个是正确的 package.json。

          在我的例子中,有两个 package.json 文件,那么您应该将其添加到服务器文件中。

          要确定哪个是正确的 package.json,请找到"scripts": { "test": "echo "Error: no test specified" &amp;&amp; exit 1" },

          在↑『这一行下面,添加"type": "module",

          【讨论】:

          • 什么是“世博会”?
          • 请问那个主题是什么:)
          • 抱歉回复晚了,如果我没记错的话,这个主题是赛博朋克2077(测试版)。但我不确定,我从上一条评论开始就更早了。
          【解决方案19】:

          我在尝试使用 import Express.js 时遇到了这个错误。

          而不是 import express from 'express';

          我用过const express = require('express');

          【讨论】:

            【解决方案20】:

            就我而言,我更新了

            "lib": [
                  "es2020",
                  "dom"
                ]
            

            "lib": [
              "es2016",
              "dom"
            ]
            

            在我的tsconfig.json文件文件。

            【讨论】:

            • 谢谢,你的评论让我安装:@babel/preset-env,通过 npm 安装,我可以使用 import 语句。
            • @Thuy很好。我很高兴你解决了这个问题
            【解决方案21】:

            我不得不从外部文件(JavaScript 文件)导入一些数据到我的脚本.js文件存在于我的 HTML 文件中。

            文件数据.js

            const data = {a: 1, b: 2}
            

            通过添加 type=module 我得到了 CORS 错误。

            我发现我可以导入文件数据.js进入我的脚本.js文件只是通过包含文件数据.js在我的 HTML 文件中。

            例如,以前我的 HTML 文件包含

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

            因为我需要文件中的一些数据数据.js,我刚刚将我的 HTML 文件更改为:

            <script src="assets/data.js"></script>
            <script src="assets/script.js"></script>
            

            即,包含文件数据.js档案前脚本.js, 允许访问我的文件中的数据变量脚本.js.

            【讨论】:

            • 你能展示一下你是如何在script.js中使用data.js的吗? script.js 不包含导入语句?
            • @parsecer,是的,script.js 文件中没有导入语句。例如。 data.js 可以有 const data_js_variable = 1 并且我们可以在 script.js 中使用这个变量而不需要任何导入语句。我们只需要在我们的 html 文件中按顺序包含 js 文件,如&lt;script src="assets/data.js"&gt;&lt;/script&gt; &lt;script src="assets/script.js"&gt;&lt;/script&gt;
            【解决方案22】:

            我刚刚将 "type": "module" 添加到我的 Package.json 文件中,它对我有用。

            【讨论】:

            【解决方案23】:

            提供的答案都不适合我,但我找到了不同的解决方案:How to enable ECMAScript 6 imports in Node.js

            安装 ESM:

            npm install --save esm
            

            使用 ESM 运行:

            node -r esm server.js
            

            【讨论】:

              【解决方案24】:

              好吧,就我而言,我不想更新我的包.json文件并将文件类型更改为 mjs。

              所以我环顾四周,发现更改文件中的模块tsconfig.json文件影响了结果。我的配置文件文件是:

              {
                "compilerOptions": {
                  "target": "es2020",
                  "module": "es2020",
                  "lib": [
                    "es2020",
                  ],
                  "skipLibCheck": true,
                  "sourceMap": true,
                  "outDir": "./dist",
                  "moduleResolution": "node",
                  "removeComments": true,
                  "noImplicitAny": true,
                  "strictNullChecks": true,
                  "strictFunctionTypes": true,
                  "noImplicitThis": true,
                  "noUnusedLocals": true,
                  "noUnusedParameters": true,
                  "noImplicitReturns": true,
                  "noFallthroughCasesInSwitch": true,
                  "allowSyntheticDefaultImports": true,
                  "esModuleInterop": true,
                  "emitDecoratorMetadata": true,
                  "experimentalDecorators": true,
                  "resolveJsonModule": true,
                  "baseUrl": "."
                },
                "exclude": [
                  "node_modules"
                ],
                "include": [
                  "./src/**/*.ts"
                ]
              }
              

              像这样并将模块从 "module": "es2020" 更改为 "module" : "commonjs" 解决了我的问题。

              我正在使用 MikroORM,并认为它可能不支持 CommonJS 以上的任何模块。

              【讨论】:

                【解决方案25】:

                那是因为你还没有出口。 .ts 文件需要导出类格式,而在 .js 文件中,我们将使用 exports 函数。

                因此,我们必须使用var_name = require("&lt;pathfile&gt;") 来使用这些文件功能。

                【讨论】:

                • 你好……检查//观察……你的回答不够详细。插入带有代码和参考的有效响应很有用。得出一个实用有效的解决方案。这个平台不仅仅是任何论坛。我们是世界上为其他程序员和开发人员提供的最大的帮助和支持中心。查看社区条款并学习如何发帖;
                【解决方案26】:

                利用

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

                代替

                <script>System.import("/src/moduleA.js")</script>
                

                【讨论】:

                  【解决方案27】:

                  对我来说这是一个编译问题。我已经添加

                    "devDependencies": {
                      ...
                      "@babel/cli": "^7.7.5",
                      "@babel/core": "^7.7.5",
                      "@babel/node": "^7.7.4",
                      "@babel/plugin-proposal-class-properties": "^7.7.4",
                      "@babel/plugin-transform-instanceof": "^7.8.3",
                      "@babel/plugin-transform-runtime": "^7.7.6",
                      "@babel/preset-env": "^7.7.5",
                      "@babel/register": "^7.7.4",
                      "@babel/runtime": "^7.9.6"
                    },
                  
                  
                    "dependencies": {
                      ...
                      "@babel/plugin-transform-classes": "^7.15.4"
                    },
                  
                  

                  添加了 .babelrc 文件

                  {
                    "plugins": [
                      "@babel/plugin-proposal-class-properties",
                      "@babel/plugin-transform-instanceof",
                      "@babel/plugin-transform-classes"
                    ],
                    "presets": ["@babel/preset-env"],
                    "env": {
                      "test": {
                        "plugins": ["@babel/plugin-transform-runtime"]
                      }
                    }
                  }
                  

                  【讨论】:

                  • 你是什​​么意思“添加了 .babelrc 文件”?添加了什么?文件中添加了一些内容.babelrc?什么内容?是文件.babelrc自己加的?去哪里?究竟添加了什么?这是否显示了一些现有内容(未添加)?为什么有两个部分的内容?请通过 editing (changing) your answer 回复,而不是在 cmets 中回复(没有“编辑:”、“更新:”或类似的 - 答案应该看起来就像是今天写的一样)。
                  【解决方案28】:

                  我想我会添加这个注释,因为它对我来说不是很明显。您需要将 type="module" 添加到所有脚本包含中,而不仅仅是要用于实用程序文件的脚本。

                  索引.html:

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

                  主.js:

                  import myFunction from './utils.js
                  

                  utils.js:

                  export default myFunction
                  

                  【讨论】:

                    【解决方案29】:

                    只需在src中的&lt;script&gt;标签中的名称和扩展名之间添加.pack即可。

                    IE。:

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

                    【讨论】:

                      【解决方案30】:

                      当它在Babel transpile 中失败时会发生此错误。

                      【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2022-11-26
                      • 1970-01-01
                      • 2022-11-23
                      • 2021-11-21
                      • 2020-08-30
                      • 2021-08-11
                      • 2022-09-26
                      相关资源
                      最近更新 更多