Home > database >  Getting "Cannot use import statement outside a module" even if I have '"type&quo
Getting "Cannot use import statement outside a module" even if I have '"type&quo

Time:11-06

I have a simple express backend which I want to test. The backend just returns a messages array when hit /messages with a GET.

Note: I understand there could be a simple fix, because I am relatively new to node.js world and have worked mostly in Python environment before. So, please, provide answer with explanation.

Here is my 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"
  }
}

Things to note:

  1. "type": "module".
  2. I'm using jest and supertest for testing my express enabled backend.

Let's see what my server.js looks like:

import app from './app.js'

const port = 3000

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

For the purpose of testing, in server.js I only have code to start the server. All the important code is in 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

Things to note:

  1. export default app

Before I proceed to show you my server.test.js, let's see my directory structure.

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

1 directory, 5 files

Now, here is my 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')
  });

});

Thing to note: import app from '../app'. I am importing app from the file called app.js which is one directory above in the tree as shown in above tree output.

Now that I have everything set up, when I go ahead with invoking the test. I get an error thrown by jest runner. I have removed some output to just show the main error:

 FAIL  tests/server.test.jsTest 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.

I have searched other question on Stackoverflow, some of them suggest doing a "type": "module" in package.json. Which I have already done. Why am I getting this error and how do I fix this?

CodePudding user response:

For jest support on ECMAScript modules, you can take a look at this GitHub Issue


In order to transpile the imports you can use Babel (jest docs).

Install babel:

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

add babel configuration by creating babel.config.js or .babelrc

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

working example on GitHub

  • Related