Jest resolver cannot find a file which path ressembles existing node modules - jestjs

I have upgraded jest from version 27 to version 29.
Since then, some indirect file resolve do not work anymore.
Here is my config:
module.exports = {
roots: ['app/javascript/__tests__/'],
testMatch: ['**/?(*.)(spec|test).js?(x)'],
testEnvironment: 'jsdom',
testRunner: 'jest-jasmine2',
moduleDirectories: [
'node_modules',
'app/javascript',
'app/javascript/__tests__'
],
transform: {
'^.+\\.jsx?$': 'babel-jest'
},
moduleNameMapper: {
'^.+\\.(svg)$': '<rootDir>/app/javascript/__tests__/fileMock.js'
},
setupFiles: ['./app/javascript/__tests__/setup.jsx']
}
There is a file in my code base, let's say app/javascript/MyReactComponent.jsx, which is imported as part of my tested component, and that contains the following import line:
// app/javascript/MyReactComponent.jsx
import 'firebase/init'
Expected behavior
Until today, I could run jest, and it was finding all my code as expected, inclluding the above import, which is located here:
app/javascript/firebase/init.js
Error
Instead, running jest throws the following error.
Cannot find module 'firebase/init' from 'app/javascript/MyReactComponent.jsx'
FWIW, I have traced the resolver code up to the default jest resolver, and it seems like it tries to get the file from within the firebase node module, instead of fetching the init.js file in the firebase directory.
Question
Is there a way to adjust my configuration in order for the resolver to find my file?

Have you tried adding an entry for that aliased module in moduleNameMapper?
moduleNameMapper: {
'^.+\\.(svg)$': '<rootDir>/app/javascript/__tests__/fileMock.js',
'^firebase/init': '<rootDir>/app/javascript/firebase/init.js'
}

Related

"SyntaxError: Cannot use import statement outside a module" when test Konva

i write a chess game by konva.js and typescript.
now i want to test it with ts-jest, but error happen when import Konva.
here is error messenge.
i know it possibly cause by esModule compiler.
i have tried to add konva in transformIgnorePatterns ,but not work.
or i should mock konva by _mock_?
how i fix it ,thanks all.
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
D:\code\chess\chess\node_modules\konva\lib\index-node.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { Konva } from './_FullInternals.js';
Here is my jest.config.js that worked for me with ts-jest:
/** #type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
moduleNameMapper: {
'^konva': 'konva/konva',
},
globals: {
'ts-jest': {
diagnostics: false,
useESM: true,
},
},
};

#babel/register support source maps on runtime

There is code that is transpiled by babel. But on runtime error it shows a wrong line number.
I run the script this way.
node -r ./runner.js ./index.js
It uses the runner.
console.log('Runner. Registers babel.')
require('source-map-support').install()
require('#babel/register')({
extensions: ['.js'],
ignore: [
/node_modules[\\/](?!console-command-manager)/
],
});
Babel register uses the config from babel.config.js
console.log('Babel. Configuration.');
module.exports = {
presets: [['#babel/preset-env', { targets: { node: 'current' } }]],
plugins: [],
sourceMap: "inline"
};
When I throw an error in the code on runtime. It shows me wrong line numbers. I understand that source-map-support does not work.
VSCode debugging goes well. The editor see and understand source maps.
Help me to make source-maps workable.
The plugin registration of babel-plugin-source-map-support in babel.config.js is missed.
Read the description of the library babel-plugin-source-map-support
There two libraries are needed: babel-plugin-source-map-support and source-map-support. Install them both.
In babel file, register source-map-support plugin
{
sourceMaps: true,
plugins: ['source-map-support', ...]
}
Enable on runtime in a file at the top.
require('source-map-support').install()
Now, when it fails it has to show the right error line number of the source code.

How can I test swiper with Jest?

I'm creating unit testing of Swiper using Jest.
Here is my code:
https://codesandbox.io/s/swiper-default-react-forked-v0dnz?file=/src/App.test.jsx
● Test suite failed to run
Cannot find module 'swiper/react' from 'src/App.jsx'
Require stack:
src/App.jsx
src/App.test.jsx
1 | import React from "react";
2 | // Import Swiper React components
> 3 | import { Swiper, SwiperSlide } from "swiper/react";
| ^
4 |
5 | // Import Swiper styles
6 | import "swiper/css";
at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:322:11)
at Object.<anonymous> (src/App.jsx:3:1)
This error has been reported all the time, but the program can run normally. Can anyone help me solve this problem?
I suppose you are having issues with Swiper 7 or newer versions because Jest doesn't support ESM packages yet.
So even if it is not the most optimal solution, you can solve it by downgrading it to Swiper 6
Run these commands:
npm uninstall swiper
npm install swiper#6.8.4
And import it this way:
import { Swiper, SwiperSlide } from 'swiper/react'
import 'swiper/swiper-bundle.min.css'
import 'swiper/swiper.min.css'
This seemed to work for me (Swiper v8):
(in package.json)
"jest": {
"moduleNameMapper": {
"swiper/react": "swiper/react/swiper-react.js",
"swiper/css": "swiper/swiper.min.css"
},
"transform": {
"^.+\\.css$": "jest-transform-css"
}
}
(and maybe also add this to transformIgnorePatterns)
'node_modules/(?!(swiper|ssr-window|dom7)/)'
If you don't care about testing Swiper v8 functionality, but want to test some other features in your components, try to add this line in your jest file:
jest.mock('Swiper', () => class Mocked {});
Worked for nextjs, doesn't complain. Maybe not the best way, but in my case it's more than enough.
I'm using Swiper 8.4.2 and this worked for me while using Swiper in Jest.
TL;DR just give me the Jest config
Here is a configuration that worked for me.
/* eslint-disable */
export default {
displayName: "components",
preset: "../../jest.preset.js",
moduleNameMapper: {
// Jest cannot understand this swiper import so we tell it where this points to
"swiper/css": "swiper/swiper.min.css",
},
transform: {
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "#nrwl/react/plugins/jest",
"^.+\\.[tj]sx?$": ["babel-jest", { presets: ["#nrwl/react/babel"] }],
},
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
coverageDirectory: "../../coverage/libs/components",
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
transformIgnorePatterns: ["node_modules/(?!swiper|ssr-window|dom7)"],
};
Important things about config
Some of the things can be ignored because they are specific to this NX controlled monorepo, but couple of things are important here. So ignore "nrwl" and "nx" specifics, because I'm expecting this part about transformers to already be configured for your project whether you are using NX or something else.
What errors was I getting?
So running tests first threw errors "Jest encountered an unexpected token" and "SyntaxError: Unexpected token 'export'" for this line in my code:
import { Navigation } from "swiper";
Actual source of the error was this line in Swiper package:
export { default as Swiper, default } from './core/core.js';
Adding swiper|ssr-window|dom7 to transformIgnorePatterns resolved that issue.
Then after adding that I got the same error, but for this line:
import "swiper/css";
One of the answers above managed to help me with this actually because it involved "moduleNameMapper" property.
So adding this into the config solved the issue with this particular import:
moduleNameMapper: {
// Jest cannot understand this swiper import so we tell it where this points to
"swiper/css": "swiper/swiper.min.css",
},
Hopefully this helps someone with resolving their issue and actually understanding what parts of the config resolved specific issues.

Jest not working with fs/promises typescript

I'm trying to add jest to my typescript project for testing, but when I run jest, it keeps giving me the error
● Test suite failed to run
Cannot find module 'fs/promises' from 'src/path/to/file'
Require stack:
src/path/to/file
test/test.ts
> 3 | import fsp from 'fs/promises';
at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:311:11)
at Object.<anonymous> (src/path/to/file.ts:3:1)
The program itself runs fine, but whenever I try to run jest on it, it runs into this issue. I've tried adding jest.mock('fs');, which didn't help, and adding jest.mock('fs/promises'); gives the same error in the test file.
I've read that certain versions of Node don't support 'fs/promises' and instead need require('fs').promises, which I've tried and still doesn't work (I'm on Node version 12).
How can I configure jest to be able to load 'fs/promises'? I've included my jest.config.js file below:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: [
'/node_modules/',
'/out/',
],
moduleDirectories: [
'.',
'node_modules'
],
moduleFileExtensions: [
'ts',
'tsx',
'js',
'jsx'
]
}
Turns out Jest is interpreting 'fs/promises' as a folder in the file system, which is incorrect as this is an API from the fs module. To fix this, simply add
moduleNameMapper: {
"fs/promises": "<rootDir>/node_modules/fs-extra/lib/fs"
}
to jest.config.js to tell Jest to map the module 'fs/promises' to the file <rootDir>/node_modules/fs-extra/lib/fs, or wherever the fs module is defined in your file system.

Error while loading config - You appear to be using a native ECMAScript module configuration file (Jest)

UPDATED.
This error is coming up when I am making a pull request. There is a github workflow audit that runs checks on the pull request and it loads the test file from another repository.
- name: Run Audits
run: npx jest audits/ch-2 --json --outputFile=audits/ch-2.json --noStackTrace
Test suite failed to run
/Users/frankukachukwu/StudioProjects/covid-19-estimator-tksilicon-js/babel.config.js: Error while loading config - You appear to be using a native ECMAScript module configuration file, which is only supported when running Babel asynchronously.
How do I solve this issue?
SOLVED: For anyone who encounters this problem. This has got to do with Babel settings. The use of .mjs, cjs or js extension for the babel.config.extension. In my case where I was running LTE Node 12.6.2. I needed this configuration at the root of my directory babel.config.cjs. cjs is what is applicable for Nodejs when using "type"="module". See more about it here on babel docs.
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current'
}
}
]
]
};
And jest.config.cjs at the root too.
In addition to "cjs" solution, I was able to resolve this issue by converting babel.config.js to babel.config.json:
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "current"
}
}
],
"#babel/preset-typescript"
]
}

Resources