【问题标题】:Getting "Cannot use import statement outside a module" even if I have '"type": "module"' in package.json即使我在 package.json 中有 '"type": "module"',也会得到“不能在模块外使用 import 语句”
【发布时间】:2021-12-19 23:40:42
【问题描述】:

我有一个简单的 Express 后端,我想对其进行测试。当使用 GET 访问 /messages 时,后端仅返回一个消息数组。

注意:我知道有一个简单的解决方法,因为我对 node.js 世界比较陌生,并且以前主要在 Python 环境中工作过。所以,请提供答案和解释。

这是我的package.json

{
  "name": "backend",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "dev": "nodemon server.js",
    "test": "jest"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.17.1"
  },
  "devDependencies": {
    "jest": "^27.3.1",
    "supertest": "^6.1.6"
  }
}

注意事项:

  1. "type": "module"
  2. 我正在使用 jest 和 supertest 来测试我启用 express 的后端。

让我们看看我的server.js 长什么样子:

import app from './app.js'

const port = 3000

app.listen(port, () => console.log('app running'))

出于测试的目的,在 server.js 中我只有启动服务器的代码。所有重要的代码都在app.js

import express from 'express'
import cors from 'cors'
const app = express()

app.use(cors())
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

const messages = ['hello', 'hi', 'its working']

app.get('/messages', (req, res) => {
  res.send(messages)
})

export default app

注意事项:

  1. export default app

在我继续向您展示我的 server.test.js 之前,让我们看看我的目录结构。

├── app.js
├── package.json
├── package-lock.json
├── server.js
└── tests
    └── server.test.js

1 directory, 5 files

现在,这是我的server.test.js

import app from '../app'
import supertest from 'supertest'
const requestWithSupertest = supertest(app);


describe('Messages Endpoints', () => {

  it('GET /messages should show all messages', async () => {
    const res = await requestWithSupertest.get('/messages');
    expect(res.status).toEqual(200);
    expect(res.type).toEqual(expect.stringContaining('json'));
    expect(res.body).toHaveProperty('messages')
  });

});

注意事项:import app from '../app'。我正在从名为 app.js 的文件中导入应用程序,该文件是树中上面的一个目录,如上图tree 输出所示。

现在我已经完成了所有设置,当我继续调用测试时。我得到一个开玩笑的跑步者抛出的错误。我删除了一些输出以显示主要错误:

 FAIL  tests/server.test.js
  ● Test suite failed to run

    Jest encountered an unexpected token

    [output trimmed...]

    Details:

    /efs/repos/vueandauth/backend/tests/server.test.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import app from '../app';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)
      at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.149 s
Ran all test suites.

我在 Stackoverflow 上搜索了其他问题,其中一些建议在 package.json 中执行 "type": "module"。我已经做过了。为什么会出现此错误,我该如何解决?

【问题讨论】:

  • tests目录下有package.json吗?
  • 没有。为了方便起见,我还在问题中发布了目录的树输出。

标签: node.js express jestjs


【解决方案1】:

关于 ECMAScript 模块的笑话支持,你可以看看这个GitHub Issue


为了转换导入,您可以使用 Babel (jest docs)。

安装 babel:

yarn add --dev babel-jest @babel/core @babel/preset-env

通过创建babel.config.js.babelrc来添加babel配置

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

working example on GitHub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 2020-01-27
    • 2020-02-11
    • 2020-12-11
    相关资源
    最近更新 更多