Closed smmoosavi closed 2 years ago
The problem is with Jest config (ESM support is very tricky with Jest). Sorry, you need to ask Jest community.
Adding nanoid to transformIgnorePatterns and moduleNameMapper to the jest.config.ts helped in my case with the same error:
import type { Config } from "@jest/types";
const esModules = ["lodash-es", "nanoid"].join("|");
const config: Config.InitialOptions = {
... // rest of your config
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
moduleNameMapper: {
"^lodash-es(/(.*)|$)": "lodash$1",
"^nanoid(/(.*)|$)": "nanoid$1",
}
};
export default config;
@ai I believe both uuid
and nanoid
have the same problem. Please see this thread for the full explanation: https://github.com/microsoft/accessibility-insights-web/pull/5421#issuecomment-1109168149.
My understanding is that some changes are required to make it compliant?
Yeah I think the issue is that Jest is now looking for package.json exports fields: https://jestjs.io/docs/upgrading-to-jest28#packagejson-exports
I dont know enough about how they work, but could be an issue with this? https://github.com/ai/nanoid/blob/fd80ce3f462d3309c31d07dc3b3ec2f3e0a0fc9f/package.json#L24-L35
Some similar discussion happening over on the uuid issue tracker: https://github.com/uuidjs/uuid/pull/616
I got it to work doing something similar to the custom jest resolver solution recommended here
The problem is that Jest use browser
version, but do not emulate browser stack fully.
You need a crypto
polyfill.
Ahh that makes sense, thanks for the fast reply! The custom jest resolver worked for me for now.
I added a note about Jest c9df0ab
I also created an issue in Jest https://github.com/facebook/jest/issues/12947
@ai I'm not sure this is only a polyfill error, because it's not really complaining about crypto, but about import
. As you can see in the screenshot, I'm specifically telling him which file to import.
Tried all of the ideas in this issue, none of them worked for me. Would anyone be so kind and share their tsconfig.json
and jest.config.js
?
No matter what I do, I'm getting this:
Thanks!
@Pavel910
I have the following in src/tests/resolver.js
:
function Resolver(path, options) {
return options.defaultResolver(path, {
...options,
packageFilter: pkg => {
if (pkg.name === 'nanoid') {
// eslint-disable-next-line
delete pkg.exports;
// eslint-disable-next-line
delete pkg.module;
}
return pkg;
},
});
}
module.exports = Resolver;
and finally in jest.config.ts
:
resolver: `<rootDir>/src/tests/resolver.js`,
@jacquesg thanks! I finally found a working combo this very minute, sharing it here if anyone runs into this issue:
The solution has 2 parts:
1) jest.config.ts
needs to process nanoid
(because it's an ESM), so we add it to transformIgnorePatterns
. We also MUST add the js
pattern to be transformed by ts-jest
(this was the missing piece for me).
2) We need to add the crypto polyfill @ai mentioned.
Another way is to switch Jest to ESM mode by Jest docs
It is unfortunate to have these type of issues where there are multiple solutions to the same problem that IMHO should not exist. Imagine not knowing how to debug or even google this. It requires a good understanding of interactions between different systems, ESM vs CJS, browser vs node, the list goes on... (I for one do not understand all of it or necessarily "care" to understand all of it).
A zeroconf solution is really the only way this doesn't continue biting developers.
A zeroconf solution is really the only way this doesn't continue biting developers
It is mostly the problem of Jest. I can recommend uvu
where nanoid
and ESM works very well.
Also there is vitest
if you need to test React.
@ai I'll check out vitest
, thank you.
jest.mock("nanoid", () => { return {
nanoid : ()=>{}
} });
use mock in setupTests.js of jest
jest.mock("nanoid", () => { return { nanoid : ()=>{} } });
use mock in setupTests.js of jest
This really worked for me.
jest.mock("nanoid", () => { return { nanoid : ()=>{} } });
use mock in setupTests.js of jest @SunXinFei Thank you this worked for me also in a nextjs app.
jest.mock("nanoid", () => { return { nanoid : ()=>{} } });
Thanks for the inspiration!
I have faker on a project, so made nanoid
do its job:
jest.mock('nanoid', () => {
return {
nanoid: () => faker.string.alphanumeric(10),
};
});
When
testEnvironment: 'jsdom'
is set it tries to loadnode_modules/nanoid/index.browser.js
and shows an error about the import syntrax.note: in
testEnvironment: 'node'
import has no problemjest config:
tsconfig
error: