question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Hi, More and more tools are using ESM modules and the support is increasing in the community.

Jest support ESM when "type": "module" is present in the package.json. On Nuxt documentation, every examples for the nuxt.config.js file are in ESM syntaxe.

But when setting up Nuxt with test-utils in ESM, an error is thrown Must use import to load ES Module: /home/node/app/nuxt.config.js because a require is used.

jest.config.js

export default {
  preset: '@nuxt/test-utils',
  transform: {},
};

nuxt.config.js

export default {
  srcDir: 'src/',
};

package.json

{
  "name": "terraforming",
  "type": "module",
  "scripts": {
    "test": "jest"
  },
  "dependencies": {
    "nuxt": "^2.15.7",
  },
  "devDependencies": {
    "@nuxt/test-utils": "^0.2.2",
    "jest": "^27.1.0",
  }
}
$ NODE_OPTIONS=--experimental-vm-modules npm test

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
mrazauskascommented, Sep 23, 2021

Back to your question. @nuxtjs/style-resources is not ESM module. File extension is .js, "type": "module" is not declared in package.json, so Node will treat this module as CJS, but will choke on export default (line 6). We can change file extension or add "type": "module", but require does not exist in ESM (it is used in the very first line). This code is written is Javascript, but according to Node’s specification this is not CJS, nor ESM module.

Should everything published on npm be a Node module? That’s not necessary at all. @nuxtjs/style-resources is a Nuxt module. Nuxt can load it, but Node cannot.

What about Jest? Jest follows Node’s module specification. So Jest cannot load Nuxt modules. Wait… Nuxt CLI runs on Node and modules are loaded as expected. Why Jest cannot do the same? Well… look here.

To be able to load Nuxt modules (the ones which are mixing CJS and ESM syntax) Nuxt is replacing the require function. In CJS module require is just another variable, one can overwrite it and nobody will complain. For example, in Node we cannot require ESM modules, but Nuxt’s require allows this. It checks the source and transforms on demand. Internally Nuxt consumes everything as CJS although it feels like you are feeding it with ESM.

All works smooth until it does not. The lines which I was referencing are detecting the Jest’s global object. If Jest is present Nuxt does not use its require function anymore. Jest’s require is used. Hm… On surface both of them are require functions, but they are not interchangeable. As I was explaining, Jest is following Node specification and it simply cannot load Nuxt modules.

Same example, one can require ESM module from inside Nuxt. It works, because everything is transformed into CJS. Jest’s require will throw, because ESM modules cannot be required, they must be imported.

Here is an idea for another workaround. Run Jest in ESM mode and include injectGlobals: false in your Jest config. There is no Jest global anymore, Nuxt cannot detect it and is using its own require. Nuxt modules are loaded as expect, but there is another problem – the Test utils depend on Jest’s globals.

If your goal is to e2e test a web app in a browser, Playwright Test Runner is better choice. If your app runs with nuxt start, you will have no trouble to test it.

If you are testing Nuxt module, Jest with Test Utils is better choice. At some point you might want to mock some dependancy (Jest will do the job), or to dig into Nuxt internals (the utils will help).

As always – choose the right tool for the job.

Hope this helps. Happy testing.

2reactions
GMartignycommented, Sep 21, 2021

Here’s a minimal repro repo.

It works until I added @nuxtjs/style-resources. Which is exporting ESM anyway, should I make it pass through babel ?

Read more comments on GitHub >

github_iconTop Results From Across the Web

What does it take to support Node.js ESM? – The Guild
I have worked on all The Guild's libraries and graphql-js to support ESM. Here is how you can do it too.
Read more >
Getting Started with (and Surviving) Node.js ESM
The Node.js ecosystem is shifting towards ESM. We examine what lies in store for application and library authors, learn some of challenges ...
Read more >
ECMAScript modules | Node.js v19.3.0 Documentation
Node.js fully supports ECMAScript modules as they are currently specified and ... Caveat: The ESM load hook and namespaced exports from CommonJS modules...
Read more >
"ESM" | Can I use... Support tables for HTML5, CSS3, etc
"Can I use" provides up-to-date browser support tables for support of front-end web technologies on desktop and mobile web browsers.
Read more >
supports-esm - npm
Detect at runtime if Node.js supports ECMAScript modules. ... Start using supports-esm in your project by running `npm i supports-esm`.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found