Related
I am trying to migrate from jest to vitest.
at some point I get this error :
Syntax Error: Invalid or unexpected token
It seems one of the packages we have in project has this line that causes the issue:
require("./lib/somefont.woff")
I checked jest and jest has this line which resolved the issue:
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
},
I was wondering how I can resolve the issue in vitest?
is there an equivalent of moduleNameMapper in vitest?
Use import to import the font
import "./lib/somefont.woff"
Try setting alias config in vitest.config.js
import { defineConfig } from 'vite'
export default defineConfig({
test: {
globals: true,
environment: "jsdom",
alias: {
".*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
},
},
});
I am trying to configure Jest in my Next.js project. In my test file, I have imported my component like import { HamburgerMenu } from './HamburgerMenu.jsx'. In that component, there are so many other imports. Once of them is
import {
checkValidEmail, getNumbers, getFormttedPhoneNo, validateSubscription,
} from 'helpers/utils';
When I run tests, it gives me the following error (which is on above import statement):
Cannot find module 'helpers/utils' from 'components/common/Smart/HamburgerMenu/HamburgerMenu.jsx'
So here are the details.
jest.config.js (at root dir)
module.exports = {
collectCoverageFrom: [
'**/*.{js,jsx,ts,tsx}',
'!**/*.d.ts',
'!**/node_modules/**',
],
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testPathIgnorePatterns: ['/node_modules/', '/.next/'],
transform: {
'^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest'
},
transformIgnorePatterns: [
'/node_modules/',
'^.+\\.module\\.(css|sass|scss)$',
],
moduleNameMapper: {
'^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
},
}
I have added jest: true in the ESLint file.
babel.config.js file (at root dir):
module.exports = {
presets: ["next/babel"],
plugins: [["babel-plugin-styled-components", { ssr: true }]]
};
You can try to add
...
moduleDirectories: ['node_modules', '.'],
...
to your jest.config.js
In React components importing assets
(ex, import logo from "../../../assets/img/logo.png)
gives such error
({"Object.":function(module,exports,require,__dirname,__filename,global,jest){�PNG
SyntaxError: Invalid or unexpected token
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:305:17)
my jest config is
"jest": {
"testRegex": ".*\\.spec\\.js$",
"moduleFileExtensions": [
"js",
"jsx",
"json"
],
"moduleDirectories": [
"node_modules",
"src",
"assets"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$/": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less|scss)$": "<rootDir>/__mocks__/styleMock.js"
},
"verbose": true,
"bail": true
}
what am i missing?
When you import image files, Jest tries to interpret the binary codes of the images as .js, hence runs into errors.
The only way out is to mock a default response anytime jest sees an image import!
How do we do this?
first you tell Jest to run the mock file each time an image import is encountered. you do this by adding the key below to your package.json file
"jest": {
"moduleNameMapper": {
"\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/mocks/fileMock.js",
"\\.(css|less)$": "<rootDir>/mocks/fileMock.js"
}
}
Note: if you already have the "Jest" key, just add the "moduleNameMapper" child in it
lastly, create a mocks folder in your root and create fileMock.js file inside it. populate the file with the snippet below
module.exports = '';
Note: If you are using es6 you can use export default ''; to avoid an Eslint flag
when you are done with the above steps, you can restart the test and you are good to go.
Note. remember to add the varying extensions of your image files in the moduleNameMapper so that they can be mocked.
I hope I have been able to help. #cheers!
For anyone looking into this problem. You have to do install npm install --save-dev identity-obj-proxy to get the necessary dependencies.
"jest": {
"moduleNameMapper": {
".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "identity-obj-proxy"
}
}
I had the same problem and I solved it as follows:
npm install -D jest-transform-stub
Then, in package.json, I added the following transformation:
"jest": {
...
"transform": {
...
".+\\.(css|scss|png|jpg|svg)$": "jest-transform-stub"
I had this same issue! I'm not sure if it's the same case as in the original question, but for me jest was still somehow trying to load the images as JS and trying to parse them while I had the files matching image extensions mapped to a mock in moduleNameMapper. My file also included some code to map the # character to the root src directory, since I had webpack and this was configured as a webpack alias in the project (and in TS). The full moduleNameMapper entry in jest.config.js looked like this for me:
moduleNameMapper: {
'^#$': '<rootDir>/src',
'^#/(.*)':
'<rootDir>/src/$1',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
// '\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'.*\\.(css|less)$': 'identity-obj-proxy',
}
For me it turned out that when I was importing the images in my components, the path was something like: '#/assets/someImage.jpg'. However, it seems this would match the first regex first, the one covering the # alias: ^#/(.*). Thus, it was being mapped to <rootDir>/src/$1 instead of the <rootDir>/__mocks__/fileMock.js.
I fixed it by making the alias only match non-images:
moduleNameMapper: {
'^#$': '<rootDir>/src',
'^#/(.*)\\.(?!jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/src/$1',
'.*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
// '\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'.*\\.(css|less)$': 'identity-obj-proxy',
}
Adding bellow line into jest.config.js file helped me to test pass,
"\\.(jpg|jpeg|png)$": "identity-obj-proxy",
Example:
moduleNameMapper: {
"\\.(css)$": "identity-obj-proxy",
"\\.(jpg|jpeg|png)$": "identity-obj-proxy",
},
If you want to use jest with webpack, you need to explicitly configure it as so. Take a look at this guide here: https://jestjs.io/docs/webpack
For those who use Vue test util in Nuxt 2 and are faced with question or this problem ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){ SyntaxError: Invalid or unexpected token
make a file with the name of fileTransformer.js in the test/unit directory, and then add these codes:
const path = require('path')
module.exports = {
process(src, filename, config, options) {
return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'
},
}
and then add these codes to jest.config.js file:
transform: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/test/unit/fileTransformer.js',
// ... other configs
},
In case of IOS image names with #
moduleNameMapper: {
"^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
"^[#./a-zA-Z0-9$_-]+\\.(png|gif)$": "RelativeImageStub"
}
In React Native we use preset: 'react-native'
https://github.com/facebook/react-native/blob/main/jest-preset.js
Or add transform into jest.config.js
transform: {
'^.+\\.(js|ts|tsx)$': 'babel-jest',
'^.+\\.(bmp|gif|jpg|jpeg|mp4|png|psd|svg|webp)$': require.resolve(
'../node_modules/react-native/jest/assetFileTransformer.js',
),
},
If you do not use React Native, need to create a file https://github.com/facebook/react-native/blob/main/jest/assetFileTransformer.js into your project and changes path into require.resolve
Nothing has worked for me, so I replaced
the 'mount' with 'shallow' everywhere and it's working fine now.
npm install --save-dev identity-obj-proxy
and add the following inside your jest.config.js :
moduleNameMapper: {
"\\.(css)$": "identity-obj-proxy",
"\\.(jpg|jpeg|png)$": "identity-obj-proxy",
},
this worked for me .
In React components importing assets
(ex, import logo from "../../../assets/img/logo.png)
gives such error
({"Object.":function(module,exports,require,__dirname,__filename,global,jest){�PNG
SyntaxError: Invalid or unexpected token
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:305:17)
my jest config is
"jest": {
"testRegex": ".*\\.spec\\.js$",
"moduleFileExtensions": [
"js",
"jsx",
"json"
],
"moduleDirectories": [
"node_modules",
"src",
"assets"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$/": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less|scss)$": "<rootDir>/__mocks__/styleMock.js"
},
"verbose": true,
"bail": true
}
what am i missing?
When you import image files, Jest tries to interpret the binary codes of the images as .js, hence runs into errors.
The only way out is to mock a default response anytime jest sees an image import!
How do we do this?
first you tell Jest to run the mock file each time an image import is encountered. you do this by adding the key below to your package.json file
"jest": {
"moduleNameMapper": {
"\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/mocks/fileMock.js",
"\\.(css|less)$": "<rootDir>/mocks/fileMock.js"
}
}
Note: if you already have the "Jest" key, just add the "moduleNameMapper" child in it
lastly, create a mocks folder in your root and create fileMock.js file inside it. populate the file with the snippet below
module.exports = '';
Note: If you are using es6 you can use export default ''; to avoid an Eslint flag
when you are done with the above steps, you can restart the test and you are good to go.
Note. remember to add the varying extensions of your image files in the moduleNameMapper so that they can be mocked.
I hope I have been able to help. #cheers!
For anyone looking into this problem. You have to do install npm install --save-dev identity-obj-proxy to get the necessary dependencies.
"jest": {
"moduleNameMapper": {
".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "identity-obj-proxy"
}
}
I had the same problem and I solved it as follows:
npm install -D jest-transform-stub
Then, in package.json, I added the following transformation:
"jest": {
...
"transform": {
...
".+\\.(css|scss|png|jpg|svg)$": "jest-transform-stub"
I had this same issue! I'm not sure if it's the same case as in the original question, but for me jest was still somehow trying to load the images as JS and trying to parse them while I had the files matching image extensions mapped to a mock in moduleNameMapper. My file also included some code to map the # character to the root src directory, since I had webpack and this was configured as a webpack alias in the project (and in TS). The full moduleNameMapper entry in jest.config.js looked like this for me:
moduleNameMapper: {
'^#$': '<rootDir>/src',
'^#/(.*)':
'<rootDir>/src/$1',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
// '\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'.*\\.(css|less)$': 'identity-obj-proxy',
}
For me it turned out that when I was importing the images in my components, the path was something like: '#/assets/someImage.jpg'. However, it seems this would match the first regex first, the one covering the # alias: ^#/(.*). Thus, it was being mapped to <rootDir>/src/$1 instead of the <rootDir>/__mocks__/fileMock.js.
I fixed it by making the alias only match non-images:
moduleNameMapper: {
'^#$': '<rootDir>/src',
'^#/(.*)\\.(?!jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/src/$1',
'.*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
// '\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'.*\\.(css|less)$': 'identity-obj-proxy',
}
Adding bellow line into jest.config.js file helped me to test pass,
"\\.(jpg|jpeg|png)$": "identity-obj-proxy",
Example:
moduleNameMapper: {
"\\.(css)$": "identity-obj-proxy",
"\\.(jpg|jpeg|png)$": "identity-obj-proxy",
},
If you want to use jest with webpack, you need to explicitly configure it as so. Take a look at this guide here: https://jestjs.io/docs/webpack
For those who use Vue test util in Nuxt 2 and are faced with question or this problem ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){ SyntaxError: Invalid or unexpected token
make a file with the name of fileTransformer.js in the test/unit directory, and then add these codes:
const path = require('path')
module.exports = {
process(src, filename, config, options) {
return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'
},
}
and then add these codes to jest.config.js file:
transform: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/test/unit/fileTransformer.js',
// ... other configs
},
In case of IOS image names with #
moduleNameMapper: {
"^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
"^[#./a-zA-Z0-9$_-]+\\.(png|gif)$": "RelativeImageStub"
}
In React Native we use preset: 'react-native'
https://github.com/facebook/react-native/blob/main/jest-preset.js
Or add transform into jest.config.js
transform: {
'^.+\\.(js|ts|tsx)$': 'babel-jest',
'^.+\\.(bmp|gif|jpg|jpeg|mp4|png|psd|svg|webp)$': require.resolve(
'../node_modules/react-native/jest/assetFileTransformer.js',
),
},
If you do not use React Native, need to create a file https://github.com/facebook/react-native/blob/main/jest/assetFileTransformer.js into your project and changes path into require.resolve
Nothing has worked for me, so I replaced
the 'mount' with 'shallow' everywhere and it's working fine now.
npm install --save-dev identity-obj-proxy
and add the following inside your jest.config.js :
moduleNameMapper: {
"\\.(css)$": "identity-obj-proxy",
"\\.(jpg|jpeg|png)$": "identity-obj-proxy",
},
this worked for me .
I am trying to get my first Jest Test to pass with React and Babel.
I am getting the following error:
SyntaxError: /Users/manueldupont/test/avid-sibelius-publishing-viewer/src/components/TransportButton/TransportButton.less: Unexpected token
> 7 | #import '../variables.css';
| ^
My package.json config for jest look like this:
"babel": {
"presets": [
"es2015",
"react"
],
"plugins": [
"syntax-class-properties",
"transform-class-properties"
]
},
"jest": {
"moduleNameMapper": {
"^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
"^[./a-zA-Z0-9$_-]+\\.png$": "RelativeImageStub"
},
"testPathIgnorePatterns": [
"/node_modules/"
],
"collectCoverage": true,
"verbose": true,
"modulePathIgnorePatterns": [
"rpmbuild"
],
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react/",
"<rootDir>/node_modules/react-dom/",
"<rootDir>/node_modules/react-addons-test-utils/",
"<rootDir>/node_modules/fbjs",
"<rootDir>/node_modules/core-js"
]
},
So what am I missing?
moduleNameMapper is the setting that tells Jest how to interpret files with different extension. You need to tell it how to handle Less files.
Create a file like this in your project (you can use a different name or path if you’d like):
config/CSSStub.js
module.exports = {};
This stub is the module we will tell Jest to use instead of CSS or Less files. Then change moduleNameMapper setting and add this line to its object to use it:
'^.+\\.(css|less)$': '<rootDir>/config/CSSStub.js'
Now Jest will treat any CSS or Less file as a module exporting an empty object. You can do something else too—for example, if you use CSS Modules, you can use a Proxy so every import returns the imported property name.
Read more in this guide.
I solved this by using the moduleNameMapper key in the jest configurations in the package.json file
{
"jest":{
"moduleNameMapper":{
"\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
"\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
}
}
}
After this you will need to create the two files as described below
__mocks__/styleMock.js
module.exports = {};
__mocks__/fileMock.js
module.exports = 'test-file-stub';
If you are using CSS Modules then it's better to mock a proxy to enable className lookups.
hence your configurations will change to:
{
"jest":{
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
},
}
}
But you will need to install identity-obj-proxy package as a dev dependancy i.e.
yarn add identity-obj-proxy -D
For more information. You can refer to the jest docs
UPDATE who use create-react-app from feb 2018.
You cannot override the moduleNameMapper in package.json but in jest.config.js it works, unfortunately i havent found any docs about this why it does.
So my jest.config.js look like this:
module.exports = {
...,
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(scss|sass|css)$": "identity-obj-proxy"
}
}
and it skips scss files and #import quite well.
Backing my answer i followed jest webpack
Similar situation, installing identity-object-proxy and adding it to my jest config for CSS is what worked for me.
//jest.config.js
module.exports = {
moduleNameMapper: {
"\\.(css|sass)$": "identity-obj-proxy",
},
};
The specific error I was seeing:
Jest encountered an unexpected token
/Users/foo/projects/crepl/components/atoms/button/styles.css:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.button { }
^
SyntaxError: Unexpected token .
1 | import React from 'react';
> 2 | import styles from './styles.css';
If you're using ts-jest, none of the solutions above will work! You'll need to mock transform.
jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
roots: [
"<rootDir>/src"
],
transform: {
".(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/jest-config/file-mock.js",
'.(css|less)$': '<rootDir>/jest-config/style-mock.js'
},
};
file-mock.js
module.exports = {
process() {
return `module.exports = 'test-file-stub'`;
},
};
style-mock.js
module.exports = {
process() {
return 'module.exports = {};';
}
};
I found this working example if you want more details.
Solution of #import Unexpected token=:)
Install package:
npm i --save-dev identity-obj-proxy
Add in jest.config.js
module.exports = {
"moduleNameMapper": {
"\\.(css|less|scss)$": "identity-obj-proxy"
}
}
Update: Aug 2021
If you are using Next JS with TypeScript. Simply follow the examples repo.
Else you will be wasting days configuring the environment.
https://github.com/vercel/next.js/tree/canary/examples/with-jest
I added moduleNameMapper at the bottom of my package.json where I configured my jest just like this:
"jest": {
"verbose": true,
"moduleNameMapper": {
"\\.(scss|less)$": "<rootDir>/config/CSSStub.js"
}
}