【问题标题】:SyntaxError: Cannot use import statement outside a moduleSyntaxError: 不能在模块外使用 import 语句
【发布时间】:2020-02-11 12:22:01
【问题描述】:

我有一个 ApolloServer 项目给我带来了麻烦,所以我想我可能会更新它并在使用最新的 Babel 时遇到问题。我的“index.js”是:

require('dotenv').config()
import {startServer} from './server'
startServer()

当我运行它时,我得到了错误

SyntaxError: Cannot use import statement outside a module

首先,我尝试让 TPTB* 相信这是一个模块(没有成功)。所以我将“import”更改为“require”,这很有效。

但现在我在其他文件中有大约两打“imports”给我同样的错误。

*我确定我的问题的根源在于我什至不确定是什么在抱怨这个问题。我有点假设它是 Babel 7(因为我来自 Babel 6,我不得不更改预设)但我不是 100% 确定。

我找到的大部分解决方案似乎都不适用于直接节点。喜欢这个:

ES6 module Import giving "Uncaught SyntaxError: Unexpected identifier"

说它是通过添加“type=module”来解决的,但这通常会出现在 HTML 中,我没有。我也尝试过使用我项目的旧预设:

"presets": ["es2015", "stage-2"],
"plugins": []

但这又给我带来了另一个错误:“错误:插件/预设文件不允许导出对象,只能导出函数。”

这是我开始使用的依赖项:

"dependencies": {
"@babel/polyfill": "^7.6.0",
"apollo-link-error": "^1.1.12",
"apollo-link-http": "^1.5.16",
"apollo-server": "^2.9.6",
"babel-preset-es2015": "^6.24.1",

【问题讨论】:

  • 嗨,现在遇到同样的问题。您还可以分享您的依赖项吗?更新前后甚至可能存在差异。我可以检查一下我的,看看我们是否能找到可能导致问题的类似包。
  • 我刚刚用“requires”替换了所有的“imports”,现在一切都很好。愚蠢,但现在不值得努力弄清楚。不过,我将使用依赖项更新原始版本。如果你有任何线索,我会对照我的原始代码检查它们。
  • CommonJS 语法(require 和 module.exports)是 node 的原始格式,webpack 也支持它,但是 ES6 模块语法(export,import)是更新的方式,现在 node 和 webpack 支持它。我读到 node 现在支持导入,但是很多教程都显示需要纯 node 的东西,所以最好使用 node 的语法。
  • 最后,对我来说,要走的路似乎是这样的:github.com/vuejs/vue-jest/issues/134#issuecomment-461755061jest.config.js 中的预设设置为'ts-jest/presets/js-with-ts' - 还有一些其他问题,但这解决了大问题。 .....嗯,是的,我的问题是测试相关的......正常的构建很好
  • "type":"module" 没有解决我的问题,imports 有一百多个。 require 的语法与 imports 不同,不是一个简单的替换。你能举例说明imports 是如何被requires 替换的吗?

标签: javascript node.js node-modules package.json npm-package


【解决方案1】:

根据the official documentation

import 语句只允许在 ES 模块中使用。有关 CommonJS 中的类似功能,请参阅 import()。

要让 Node.js 将您的文件视为 ES 模块,您需要 (Enabling):

  • 在 package.json 中添加 "type": "module"
  • 在 Node.js 调用中添加“--experimental-modules”标志

【讨论】:

  • 2020 年更新:--experimental-modules 不再需要。
  • @Cullub 应该用什么?
  • 你根本不需要任何标志。
  • 并不是说这个答案是错误的,我看过相同的文档。但我看不出在 CommonJS 中使用 import() 访问 es6 模块的建议有什么用。它是异步的,因此不能用于在文件级别导入任何内容。至少可以说,这使得尝试从 CommonJS 访问 es6 模块很痛苦。考虑到主要的单元测试框架 Jasmine Jest 等根本不能很好地处理这个问题,这让我认为,在有更好的互操作支持之前,整个 Node es6 的情况对我来说似乎是半生不熟,但我很想被证明是错误的。
  • 是我还是这样,导入/模块的事情变得绝对复杂。 Somone 只需按下重置按钮,让所有 JS 框架使用相同的东西。
【解决方案2】:

我遇到了同样的问题,以下已解决(使用 Node.js 12.13.1):

  • .js文件扩展名更改为.mjs
  • 在运行应用时添加 --experimental-modules 标志。
  • 可选:在您的package.json 中添加"type": "module"

更多信息:https://nodejs.org/api/esm.html

【讨论】:

    【解决方案3】:

    确认您已安装最新版本的 Node.js(或至少 13.2.0+)。然后执行以下操作之一,如described in the documentation

    选项 1

    在最近的父package.json 文件中,添加值为"module" 的顶级"type" 字段。这将确保所有.js.mjs 文件都被解释为ES 模块。您可以使用 .cjs 扩展名将单个文件解释为 CommonJS

    // package.json
    {
      "type": "module"
    }
    

    选项 2

    使用.mjs 扩展名明确命名文件。所有其他文件,例如.js 将被解释为CommonJS,如果type 未在package.json 中定义,则这是默认值。

    【讨论】:

    • 如果我使用这个,然后更改路径以包含所需文件的“js”,然后更改所需文件中导出语句的格式,然后取所有“require”语句我从“import”更改——因为现在“require”是未知的——这会起作用,所以我会接受这个答案。
    • 如果问题出在 node_modules/ 下,这不是一个真正的选择,对吧?在这种情况下如何解决的任何想法?
    • 或者使用 babel! ` module.exports = { 预设:['@babel/preset-env'], }; `
    • @Cocuba 的答案是正确的,应该是公认的答案,因为它实际上可以转换。
    • 如果您正在运行 .ts 文件,此解决方案将不起作用。如果您可以简单地使用nodemon 而不是node 添加它,根据下面的stackoverflow.com/a/65058291/11664580 答案,它有望为人们节省半天的时间。或者,安装ts-node 似乎是一种解决方案,根据stackoverflow.com/a/61947868/11664580
    【解决方案4】:

    我的解决方案是在运行 nodemon 时包含 babel-node 路径,如下所示:

    nodemon node_modules/.bin/babel-node index.js
    

    您可以将 package.json 脚本添加为:

    debug: nodemon node_modules/.bin/babel-node index.js
    

    注意:我的入口文件是 index.js。将其替换为你的入口文件(很多都有app.js/server.js)。

    【讨论】:

      【解决方案5】:
      1. 我刚开始用Babel的时候也遇到了同样的问题...但是后来我 有一个解决方案......到目前为止我还没有遇到过这个问题...... 目前,Node.js v12.14.1, "@babel/node": "^7.8.4",我使用 babel-node 和 nodemon 执行(Node.js 也可以..)
      2. package.json: "start": "nodemon --exec babel-node server.js "debug": "babel-node debug server.js"!!注意:server.js 是我的条目 文件,您可以使用自己的文件。
      3. launch.json。当你调试的时候,你还需要配置你的launch.json文件“runtimeExecutable”: “${workspaceRoot}/node_modules/.bin/babel-node”!!注:加号 runtimeExecutable 到配置中。
      4. 当然,使用 babel-node,您通常还需要和编辑另一个文件,例如 babel.config.js/.babelrc 文件

      【讨论】:

        【解决方案6】:

        我在一个刚刚起步的 Express API 项目中遇到了这个问题。

        src/server/server.js 中的违规服务器代码:

        import express from 'express';
        import {initialDonationItems, initialExpenditureItems} from "./DemoData";
        
        const server = express();
        
        server.get('/api/expenditures', (req, res) => {
          res.type('json');
          res.send(initialExpenditureItems);
        });
        
        server.get('/api/donations', (req, res) => {
          res.type('json');
          res.send(initialDonationItems);
        });
        
        server.listen(4242, () => console.log('Server is running...'));
        

        这是我的依赖项:

        {
          "name": "contributor-api",
          "version": "0.0.1",
          "description": "A Node backend to provide storage services",
          "scripts": {
            "dev-server": "nodemon --exec babel-node src/server/server.js --ignore dist/",
            "test": "jest tests"
          },
          "license": "ISC",
          "dependencies": {
            "@babel/core": "^7.9.6",
            "@babel/node": "^7.8.7",
            "babel-loader": "^8.1.0",
            "express": "^4.17.1",
            "mysql2": "^2.1.0",
            "sequelize": "^5.21.7",
            "sequelize-cli": "^5.5.1"
          },
          "devDependencies": {
            "jest": "^25.5.4",
            "nodemon": "^2.0.3"
          }
        }
        

        这是引发错误的跑步者:

        nodemon --exec babel-node src/server/server.js --ignore dist
        

        这令人沮丧,因为我有一个类似的 Express 项目运行良好。

        解决方法是先添加这个依赖:

        npm install @babel/preset-env
        

        然后在项目根目录中使用babel.config.js 连接它:

        module.exports = {
          presets: ['@babel/preset-env'],
        };
        

        我不完全理解为什么会这样,但我从an authoritative source 复制了它,所以我很乐意坚持下去。

        【讨论】:

        • 是的,我的问题是代码有 bunch 的预设,我永远无法完全平衡我想要的东西和我不想要的东西/弄坏了东西。
        • 我整天都在处理令人困惑的 JS 崩溃问题 @user3810626 - 我怀疑我的问题是我对语言和生态系统还很陌生,我需要暂时搁置一些学习让东西工作。到达那里...:-)
        • 祝你好运!外面是丛林! (我的意思是,从字面上看,JS 生态系统是一片丛林……)
        • @user3810626 nodejs 开发人员不知道事情是如何工作的了。他们只是不断尝试Stack Overflow 解决方案,直到出现问题
        • 这在某些社区似乎比其他社区更真实。
        【解决方案7】:

        我遇到了同样的问题,而且更糟:我需要“import”和“require”

        1. 一些较新的 ES6 模块仅适用于 import
        2. 一些 CommonJSrequire 一起使用。

        这对我有用:

        1. 按照其他答案中的建议将您的 js 文件转换为 .mjs

        2. "require" 没有用 ES6 模块定义,所以你可以这样定义:

          import { createRequire } from 'module'
          const require = createRequire(import.meta.url);
          

          现在 'require' 可以正常使用了。

        3. import 用于 ES6 模块,require 用于 CommonJS。

        一些有用的链接:Node.js's own documentationdifference between import and requireMozilla has some nice documentation about import

        【讨论】:

          【解决方案8】:

          对于那些在阅读答案时和我一样困惑的人,请在您的 package.json 文件中添加 "type": "module" 在上层如下图:

          {
            "name": "my-app",
            "version": "0.0.0",
            "type": "module",
            "scripts": { ...
            },
            ...
          }
          

          【讨论】:

          • tx,但是你知道我在哪里可以找到 package.json 吗?我正在使用netbeans。我还在我的 macbook 上搜索了 package.json,但我看到了很多 package.json 文件。有什么建议吗?
          • 嗨,Alex,在 Java 项目中工作已经有一段时间了,但我希望这个链接可以为您提供有关在哪里找到 package.json 文件的线索:stackoverflow.com/questions/41513559/…
          【解决方案9】:

          只需添加--presets '@babel/preset-env'

          例如,

          babel-node --trace-deprecation --presets '@babel/preset-env' ./yourscript.js
          

          或者

          babel.config.js

          module.exports = {
            presets: ['@babel/preset-env'],
          };
          

          【讨论】:

            【解决方案10】:

            只需将其更改为:

            const uuidv1 = require('uuid');
            

            它会正常工作的。

            【讨论】:

            • 似乎与问题无关
            【解决方案11】:

            如果有人遇到TypeScript 的这个问题,那么为我解决问题的关键是改变

                "target": "esnext",
                "module": "esnext",
            

                "target": "esnext",
                "module": "commonjs",
            

            在我的tsconfig.json。我的印象是“esnext”是“最好的”,但这只是一个错误。

            【讨论】:

            • 如果您使用的是babel-node,那么您还需要使用--extensions 选项,例如babel-node --extensions \".ts,.tsx\" src/index
            • 是的,这是在尝试“type”时做到的:“module”突然说“require is undefined”。
            • 该死的,它让我免于很多麻烦。在esnext 是最好的印象下,我犯了同样的错误
            【解决方案12】:

            第一步

            yarn add esm
            

            npm i esm --save
            

            第 2 步

            package.json

              "scripts": {
                "start": "node -r esm src/index.js",
              }
            

            第 3 步

            nodemon --exec npm start
            

            【讨论】:

            • 当您无法将"type": "module" 添加到package.json 文件时,+1 esm 似乎是最简单的解决方案。
            【解决方案13】:

            首先我们将安装@babel/cli, @babel/core and @babel/preset-env:

            npm install --save-dev @babel/cli @babel/core @babel/preset-env
            

            然后我们会创建一个.babelrc文件来配置Babel:

            touch .babelrc
            

            这将承载我们可能想要配置 Babel 的任何选项:

            {
              "presets": ["@babel/preset-env"]
            }
            

            随着最近对 Babel 的更改,您需要先编译 ES6,然后 Node.js 才能运行它。

            所以,我们将在 package.json 文件中添加我们的第一个脚本 build。

            "scripts": {
              "build": "babel index.js -d dist"
            }
            

            然后我们将在文件 package.json 中添加我们的启动脚本。

            "scripts": {
              "build": "babel index.js -d dist", // replace index.js with your filename
              "start": "npm run build && node dist/index.js"
            }
            

            现在让我们启动我们的服务器。

            npm start
            

            【讨论】:

              【解决方案14】:

              运行命令时也会出现此错误

              node filename.ts
              

              而不是

              node filename.js
              

              简单地说,使用node 命令,我们将不得不运行 JavaScript 文件 (filename.js) 而不是 TypeScript 文件,除非我们使用像 ts-node 这样的包.

              【讨论】:

                【解决方案15】:

                如果您正在为 Node.js 版本 12 运行 nodemon,请使用此命令。

                server.jspackage.json 文件中的“main”,将其替换为 package.json 文件中的相关文件:

                nodemon --experimental-modules server.js
                

                【讨论】:

                • 此标志似乎已从最新版本中删除
                【解决方案16】:

                我最近遇到了这个问题。对我有用的修复是将其添加到插件部分的文件 babel.config.json 中:

                ["@babel/plugin-transform-modules-commonjs", {
                    "allowTopLevelThis": true,
                    "loose": true,
                    "lazy": true
                  }],
                

                我有一些带有 // 的导入模块,并且错误“不能在模块外使用导入”。

                【讨论】:

                  【解决方案17】:

                  要使您的导入工作并避免其他问题,例如在 Node.js 中无法工作的模块,请注意:

                  使用 ES6 模块,您还不能导入目录。您的导入应如下所示:

                  import fs from './../node_modules/file-system/file-system.js'
                  

                  【讨论】:

                    【解决方案18】:

                    我尝试了所有方法,但没有任何效果。

                    我从 GitHub 获得了一份参考资料。

                    为了在 Node.js 中使用 TypeScript 导入,我安装了以下软件包。

                    1. npm i typescript
                    
                    2. npm i ts-node
                    

                    不需要类型:package.json 中的模块

                    例如,

                    {
                      "name": "my-app",
                      "version": "0.0.1",
                      "description": "",
                      "scripts": {
                    
                      },
                      "dependencies": {
                        "knex": "^0.16.3",
                        "pg": "^7.9.0",
                        "ts-node": "^8.1.0",
                        "typescript": "^3.3.4000"
                      }
                    }
                    

                    【讨论】:

                    • 我遇到了同样的问题。作为替代方案,只需使用 nodemon 而不是 node 运行 package.json 脚本也可以。无需安装另一个包(假设您已经在运行 nodemon)。信用:stackoverflow.com/a/65058291/11664580
                    • 是的,这救了我!谢谢!
                    • 他们应该转到 devDependencies。
                    【解决方案19】:

                    就我而言。我认为问题出在标准的node 可执行文件中。 node target.ts

                    我用nodemon 替换了它,令人惊讶的是它起作用了!

                    使用标准可执行文件(runner)的方式:

                    node target.ts
                    

                    使用nodemon可执行文件(runner)的方式:

                    nodemon target.ts
                    

                    别忘了用npm install nodemon 安装nodemon ;P

                    注意:这对开发非常有用。但是,对于运行时,您可以使用已编译的 js 文件执行 node

                    【讨论】:

                    • 也许 nodemon 将文件作为模块执行,因此本质上错误消失了
                    【解决方案20】:

                    我在运行迁移时遇到了这个问题

                    它的 es5 vs es6 问题

                    我是这样解决的

                    我跑

                    npm install @babel/register
                    

                    并添加

                    require("@babel/register")
                    

                    在我的 .sequelizerc 文件的顶部

                    然后继续运行我的续集迁移。 这适用于除了sequelize之外的其他东西

                    babel 进行转译

                    【讨论】:

                      【解决方案21】:

                      在 package.json 中写入 { “类型”:“模块” }

                      它解决了我的问题,我遇到了同样的问题

                      【讨论】:

                      • 上面给出了相同的答案,得到了很多人的支持。
                      【解决方案22】:

                      我发现此链接中答案的 2020 年更新有助于回答此问题并告诉您为什么这样做:

                      Using Node.js require vs. ES6 import/export

                      摘录如下:

                      2020 年更新

                      从 Node v12 开始,默认启用对 ES 模块的支持,但在撰写本文时它仍处于试验阶段。包含节点模块的文件必须以 .mjs 结尾,或者最近的 package.json 文件必须包含“type”:“module”。 Node 文档有大量信息,还有关于 CommonJS 和 ES 模块之间的互操作。”

                      【讨论】:

                      • 彼得,你刚刚编辑了我的语法吗?大部分都是我故意做的。你没有更好的事情要做吗?
                      【解决方案23】:

                      如果你使用节点,你应该参考这个document。只需在您的节点应用程序中设置 babel,它就可以工作并且对我有用。

                      npm install --save-dev @babel/cli @babel/core @babel/preset-env
                      

                      【讨论】:

                      • 这对我不起作用
                      【解决方案24】:

                      节点 v14.16.0
                      对于那些尝试过 .mjs 并获得的人:

                      Aviator@AW:/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex$ node just_js.mjs
                      file:///mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex/just_js.mjs:3
                      import fetch from "node-fetch";
                             ^^^^^
                      
                      SyntaxError: Unexpected identifier
                      

                      谁尝试过import fetch from "node-fetch";
                      谁试过const fetch = require('node-fetch');

                      Aviator@AW:/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex$ node just_js.js
                      (node:4899) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
                      (Use `node --trace-warnings ...` to show where the warning was created)
                      /mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex/just_js.js:3
                      import fetch from "node-fetch";
                      ^^^^^^
                      
                      SyntaxError: Cannot use import statement outside a module  
                      

                      谁尝试过 "type": "module" 到 package.json,但仍然看到错误,

                      {
                        "name": "test",
                        "version": "1.0.0",
                        "description": "to get fetch working",
                        "main": "just_js.js",
                        "type": "module",
                        "scripts": {
                          "test": "echo \"Error: no test specified\" && exit 1"
                        },
                        "author": "",
                        "license": "MIT"
                      }
                      

                      我可以毫无问题地切换到 axios。

                      import axios from 'axios'; 示例:

                      axios.get('https://www.w3schools.com/xml/note.xml').then(resp => {
                      
                          console.log(resp.data);
                      });
                      

                      【讨论】:

                        【解决方案25】:

                        我遇到了同样的问题,我在我的 Nodejs 应用中复制了 import 语句。我通过使用require 而不是import 来修复它。

                        【讨论】:

                          【解决方案26】:

                          手动升级后,我的 NX 工作区 中出现此错误。每个jest.config.js 中的以下更改修复了它:

                          transform: {
                            '^.+\\.(ts|js|html)$': 'jest-preset-angular',
                          },
                          

                          transform: {
                            '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular',
                          },
                          

                          【讨论】:

                            【解决方案27】:

                            如果你想使用 BABEL,我有一个简单的解决方案!

                            记住这是针对 nodejs 的例子:就像一个 expressJS 服务器!

                            如果你打算使用 react 或其他框架,请查看 babel 文档!

                            首先,安装(不要安装不必要的东西,只会破坏你的项目!)

                            npm install --save-dev @babel/core @babel/node
                            

                            只需 2 WAO

                            然后在你的 repo 中配置你的 babel 文件!

                            文件名:

                            babel.config.json
                            

                            {
                                "presets": ["@babel/preset-env"]
                            }
                            


                            如果不想使用 babel 文件,请使用:

                            在您的控制台中运行,script.js 是您的入口点!

                            npx babel-node --presets @babel/preset-env -- script.js
                            

                            完整信息在这里; https://babeljs.io/docs/en/babel-node

                            【讨论】:

                              【解决方案28】:

                              即使在 package.json 文件中添加 "type": "module" 后,由于 Netlify 函数中的此错误而来到此线程的人,请更新您的 netlify.toml 以使用“esbuild”。由于 esbuild 支持 ES6,它可以工作。

                              [functions]
                                node_bundler = "esbuild"
                              

                              参考: https://docs.netlify.com/functions/build-with-javascript/#automated-dependency-bundling

                              【讨论】:

                                【解决方案29】:

                                要使用导入,请执行以下操作之一。

                                1. .js 文件重命名为 .mjs
                                2. package.json 文件中,添加 {type:module}

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 2021-08-06
                                  • 1970-01-01
                                  • 2021-10-15
                                  • 2020-12-31
                                  • 1970-01-01
                                  • 2022-07-19
                                  相关资源
                                  最近更新 更多