I'm currently going through the process of upgrading from Jest 27 to 29.
I've noticed this in the 28 upgrade docs: https://jestjs.io/docs/28.x/upgrading-to-jest28#packagejson-exports.
Am I understanding correctly that if I'm testing under the jest-environment-jsdom environment, that I won't be able to import a library that doesn't export an ESM module? This seems to be the behaviour I'm observing but want to solidify my understanding.
From what I'm observing, the opposite is true. For example, their problem with uuid
is that it only exports ESM (for browsers), but Jest needs CJS. I tested this with a local package:
package.json
:
{
"private": true,
"devDependencies": {
"jest": "^29.0.3",
"jest-environment-jsdom": "^29.0.3",
"my-pkg": "file:./my-pkg"
}
}
jest.config.js
:
module.exports = {
testEnvironment: 'jsdom',
}
my-pkg/package.json
:
{
"name": "my-pkg",
"version": "0.1.0",
"exports": {
".": {
"browser": {
"require": "./browser-require.js",
"import": "./browser-import.js"
}
}
}
}
my-pkg/browser-require.js
:
module.exports = 'browser require'
my-pkg/browser-import.js
:
export default 'browser import'
And finally, the test:
const myPkg = require('my-pkg')
test('test', () => {
expect(myPkg).toBe('browser require')
})
The test passes, meaning that Jest chose the CJS version. If I remove the CJS export from my-pkg
, Jest fails with Cannot find module 'my-pkg'
. I assume that Jest would use the ESM export only if you enable experimental ESM support. In case of uuid
, they have a "default"
export, which Jest will fail to parse as CJS because it's in ESM, resulting in the error they describe.
P.S. Even with Babel Jest would still use CJS, Babel just compiles ESM to CJS before running your tests. And only your source and test code, not dependencies, so it wouldn't compile my-pkg
.