I've created a Yarn Workspace, it contains of two packages: Client and Service.
When my Component in the Client package imports a module from the Service package, Jest throws the above error.
Here is how mi jest.config.js looks like
const rootTestModule = '<rootDir>';
module.exports = {
testEnvironment: 'jest-environment-jsdom',
testMatch: ['**/?(*.)(test).js?(x)'],
transform: {
'^.+\\.jsx?$': `${rootTestModule}/jest/babel-preprocessor.js`,
},
moduleNameMapper: {
'\\.scss$': require.resolve('./style-mock.js'),
},
snapshotSerializers: ['jest-emotion'],
transformIgnorePatterns:['<rootDir>/node_modules/(?!#rppm)'],
};
Here is the babel-preprocessor.js file
const { createTransformer } = require('babel-jest');
const babelConfig = {
presets: ['#babel/env', '#babel/react'],
plugins: [
'#babel/plugin-proposal-class-properties',
'#babel/plugin-proposal-object-rest-spread',
'#babel/plugin-proposal-export-default-from',
'#babel/plugin-transform-runtime',
'transform-es2015-modules-commonjs',
]
};
Here is the package im trying to use
Related
I am receiving the error SyntaxError: Cannot use import statement outside a module when running a simple test on a React/Typescript component and not sure the best way of using modules in a React/Typescript project with Babel, webpack, and jest.
Here is my babel.config.js :
const isTest = String(process.env.NODE_ENV) === 'test'
const isProd = String(process.env.NODE_ENV) === 'production'
module.exports = {
presets: [
['#babel/preset-env', { modules: isTest ? 'commonjs' : false }],
'#babel/preset-typescript',
};
jest.config.js
module.exports = {
"roots": [
"<rootDir>/src"
],
"testMatch": [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
},
"moduleFileExtensions": ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
}
Here is the simple test I am trying to run:
import { render } from '#testing-library/react'
import AppRouter from '../router'
test('it works!', () => {
render(<AppRouter />)
})
Please help!
Solution
Be sure to check your testRegex in your jest.config.js file and the testEnvironment is set correctly with testEnvironment: "jsdom" if you are using ES6 modules for testing.
Have got a successful jest/esm setup, however occasionally a module is released that specifies both a main key (for commonjs) and a module key (for ESM) in its package.json. This leads to jest errors, for example with the uuid module:
/repo/path/node_modules/uuid/dist/esm-browser/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { default as v1 } from './v1.js';
^^^^^^
SyntaxError: Unexpected token 'export'
I can see that dist/esm-browser/index.js is the file specified by the module key in package.json.
How can Jest w/ESM be configured to handle these cases, where stuff in node_modules is ESM?
Jest config:
{
"resetMocks": true,
"testEnvironment": "jsdom",
"testMatch": [
"**/src/**/*.(spec|test).[tj]s?(x)"
],
"preset": "ts-jest/presets/default-esm",
"extensionsToTreatAsEsm": [
".ts",
".tsx"
],
"globals": {
"ts-jest": {
"useESM": true
}
},
"globalSetup": "<rootDir>/jest/setup.cjs",
"globalTeardown": "<rootDir>/jest/teardown.cjs",
"watchPathIgnorePatterns": [
"<rootDir>/.tmp"
],
"moduleNameMapper": {
"^~/(.*)$": "<rootDir>/src/$1",
"^~components/(.*)$": "<rootDir>/src/components/$1",
"^~util/(.*)$": "<rootDir>/src/util/$1",
"^~types/(.*)$": "<rootDir>/src/types/$1"
}
}
If transformIgnorePatterns doesn't work for some reason, you can solve it with moduleNameMapper.
moduleNameMapper: {
// '^uuid$': '<rootDir>/node_modules/uuid/dist/index.js',
'^uuid$': require.resolve('uuid'),
}
I've had the same problem and it was fixed the same way as mentioned in this comment: https://github.com/nrwl/nx/issues/812#issuecomment-429420861 in my jest.config.js:
// list to add ESM to ignore
const esModules = ['uuid'].join('|');
// ...
module.exports = {
//...
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
// ...
};
I am trying to make SSR version of the react-boilerplate so I need to import React component to the node. However, #babel/register does not seem to transform code based on my babel.config.js
server/index.js file require('frontendMiddleware.js')
and in the frontendMiddleware.js
module.exports = (app, options) => {
const isProd = process.env.NODE_ENV === 'production';
if (isProd) {
require('#babel/register')(require('../../babel.config.js'));
const addProdMiddlewares = require('./addProdMiddlewares');
addProdMiddlewares(app, options);
} else {
const webpackConfig = require('../../internals/webpack/webpack.dev.babel');
const addDevMiddlewares = require('./addDevMiddlewares');
addDevMiddlewares(app, webpackConfig);
}
return app;
};
Error on node server starts
import React from 'react'
^^^^^
SyntaxError: Unexpected identifier
babel.config.js
module.exports = {
presets: [
[
'#babel/preset-env',
{
modules: false,
},
],
'#babel/preset-react',
],
plugins: [
'styled-components',
'#babel/plugin-proposal-class-properties',
'#babel/plugin-syntax-dynamic-import',
],
env: {
production: {
plugins: [
'lodash',
'transform-react-remove-prop-types',
'#babel/plugin-transform-react-inline-elements',
'#babel/plugin-transform-react-constant-elements',
],
},
test: {
plugins: [
'#babel/plugin-transform-modules-commonjs',
'dynamic-import-node',
],
},
},
};
I have seen my project have exactly same setup for react ssr but this one does not work.
In my jest.config.js file, I need to populate globals property. For populating the globals property I need to require local modules, as shown below:
const path = require('path')
const server = require('./server/cfg')
module.exports = {
rootDir: path.resolve(__dirname),
moduleFileExtensions: [
'js',
'json',
'vue',
'ts'
],
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/src/$1'
},
transform: {
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest",
"^.+\\.(js|jsx)?$": "<rootDir>/node_modules/babel-jest",
"^.+\\.ts$": "<rootDir>/node_modules/ts-jest"
},
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
snapshotSerializers: [
"jest-serializer-vue"
],
setupFiles: [
"<rootDir>/globals.js"
],
testEnvironment: "jsdom",
globals: {
server: {
server
}
}
}
Whit this configuration, I get the following error:
Error: Cannot find module './server/cfg'
This is my folder structure
server/
cfg.ts
src/
jest.config.js
webpack.config.js
However, I can require node's built-in modules. I'm not able to figure out why it is happening. Any ideas on how I can overcome this?
Jest is initiated by node, not ts-node and it's not able to resolve the .ts file by default.
Probably adding setupFilesAfterEnv will help you.
jest.config.js
module.exports = {
// ... your config
setupFilesAfterEnv: [
"<rootDir>/environmentWithServer.ts`
]
}
environmentWithServer.ts
global.server = require('./server/cfg');
I'm trying to run some React tests using Mocha. My react components have aliases via Babel's "babel-plugin-module-resolver": "^3.1.1",, they work, but they don't work when running tests.
Here is the error when running testes:
Error: Cannot find module 'Styles/dimensions'
Here are my .babelrc configs:
...
"plugins": [
[ "module-resolver",
{
"root": ["."],
"extensions": [".js", ".json", ".jsx", ".ts", ".tsx"],
"alias": {
"Styles": ["./app/react/styles"],
}
}
]
]
...
My mocha-setup.js file includes:
require('moment');
require('babel-plugin-module-resolver');
require('babel-polyfill');
require('babel-register')({
only: /(node_modules\/|\.test.js)/,
});
require('ts-node').register({
project: './app/tests/config/tsconfig.test.json',
});
require('./helpers');
require('./browser');
Here is my command used to run the tests:
cross-env NODE_PATH=./ NODE_ENV=test mocha 'app/react/**/*.test.{js,jsx}' --require ./app/tests/config/mocha-setup.js
Any ideas on how to get Mocha to compile those aliases? The test run file without the alias, but Mocha doesn't seem to be running the alias compilation before running the tests.
I've solved this problem by this code in .babelrc.js:
const module_resolver = [
"module-resolver",
{
extensions: [".js", ".jsx", ".es", ".es6", ".mjs"],
root: ["./"],
alias: {
"#store": "./src/store"
},
},
];
const presets = ()=>{
return [
"#babel/preset-env",
"#babel/preset-react"
]
}
const plugins = ()=>{
let base = [
["#babel/plugin-proposal-class-properties"],
["#babel/transform-runtime"]
];
if (process.env.NODE_ENV='test')
{
base.push(module_resolver);
}
return base;
}
let config = {
presets: presets(),
plugins: plugins()
};
module.exports = config;