I am having an issue with Jest when it comes to testing certain components using Babel, Typescript, React, and Jest.
While testing a React/Typescript component I get SyntaxError: Cannot use import statement outside a module
.
Things I have tried:
ts-jest
ts-jest
ESM Support from docsHere is the jest.config.js
:
const ignores = ['/node_modules/'];
module.exports = {
preset: 'ts-jest',
roots: ['<rootDir>'],
modulePaths: [
"<rootDir>/src"
],
moduleDirectories: [
"node_modules",
],
transformIgnorePatterns: [...ignores],
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
'^.+\\.(gif|svg|ico)$': '<rootDir>/svgTransform.js',
},
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.js?$',
moduleFileExtensions: ['tsx', 'js', 'ts'],
moduleNameMapper: {
"\\.(css|less|scss|sass)$": "identity-obj-proxy",
'^(\\.{1,2}/.*)\\.js$': '$1',
},
clearMocks: true,
// collectCoverage: true, // todo
// coverageDirectory: "coverage", // todo
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect', './src/tests/setup.js'],
resolver: 'jest-webpack-resolver',
}
Here is the babel.config.js
:
module.exports = {
// For transformation of TSX and other react related bable plugins
presets: [
['@babel/preset-env', {
targets: { esmodules: false, node: "current" }
}],
// Enabling Babel to understand TypeScript
'@babel/preset-typescript', "@babel/preset-react"
],
plugins: ['@babel/plugin-transform-modules-commonjs', '@babel/plugin-transform-runtime'],
}
Here is the Code-Trace of error:
package.json
:
{
"name": "@unirep-social/frontend",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "webpack-dev-server",
"start-local": "webpack-dev-server",
"build": "webpack",
"lint": "prettier .",
"build:worker": "webpack --config webpack.worker.js",
"postinstall": "link-module-alias && yarn copyCircuits",
"copyCircuits": "node scripts/copy_circuits",
"test": "jest --config ./jest.config.js",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
},
"_moduleAliases": {
"worker_threads": "./externals/worker_threads.js"
},
"dependencies": {
"@babel/plugin-transform-runtime": "^7.18.6",
"@babel/preset-env": "^7.18.6",
"@types/react": "^17.0.15",
"@types/react-dom": "^17.0.9",
"@unirep/circuits": "git+https://github.com/Unirep/circuits.git#alpha",
"@unirep/crypto": "git+https://github.com/Unirep/crypto.git",
"@unirep/unirep": "git+https://github.com/Unirep/unirep.git#alpha",
"@unirep/unirep-social": "git+https://github.com/Unirep/unirep-social.git#alpha",
"babel-preset-env": "^1.7.0",
"bootstrap": "^5.0.2",
"dateformat": "^4.5.1",
"ethers": "^5.5.4",
"identity-obj-proxy": "^3.0.0",
"jest-environment-jsdom": "^28.1.2",
"keyv": "4.1.1",
"markdown-it": "^12.3.2",
"mobx": "^6.4.2",
"mobx-react-lite": "^3.3.0",
"n-readlines": "^1.0.1",
"nanoid": "^4.0.0",
"node-sass": "^6.0.1",
"react": "^17.0.2",
"react-circular-progressbar": "^2.0.4",
"react-dom": "^17.0.2",
"react-favicon": "^1.0.0",
"react-icons": "^4.2.0",
"react-jdenticon": "^0.0.9",
"react-router-dom": "^5.2.0",
"react-router-hash-link": "^2.4.3",
"snarkjs": "^0.3.59",
"ts-jest": "^28.0.5"
},
"devDependencies": {
"@babel/core": "^7.18.6",
"@babel/plugin-transform-modules-commonjs": "^7.18.6",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@cloudflare/kv-asset-handler": "^0.2.0",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "12.1.5",
"@testing-library/user-event": "^14.2.1",
"@types/jest": "^28.1.4",
"@types/keyv": "^3.1.2",
"@types/markdown-it": "^12.2.3",
"@types/n-readlines": "^1.0.2",
"@types/react-router-dom": "^5.1.8",
"@types/shelljs": "^0.8.9",
"assert": "^2.0.0",
"babel-jest": "^28.1.2",
"babel-loader": "^8.2.3",
"buffer": "^6.0.3",
"crypto-browserify": "^3.12.0",
"css-loader": "^6.7.1",
"css-minimizer-webpack-plugin": "^3.4.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"jest": "^28.1.2",
"jest-axe": "^6.0.0",
"jest-webpack-resolver": "^0.3.0",
"link-module-alias": "^1.2.0",
"mini-css-extract-plugin": "^2.6.0",
"os-browserify": "^0.3.0",
"prettier": "^2.6.0",
"react-test-renderer": "^18.2.0",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"stream-browserify": "^3.0.0",
"ts-loader": "^9.2.8",
"typescript": "^4.3.5",
"url-loader": "^4.1.1",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
},
"jestWebpackResolver": {
"webpackConfig": "./webpack.config.js"
},
"prettier": {
"tabWidth": 4,
"singleQuote": true,
"semi": false
}
}
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
// const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin')
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const webpack = require('webpack')
module.exports = {
entry: ['./src/index.tsx'],
mode: 'development',
devServer: {
port: 3000,
// proxy: {
// '/api': {
// target: 'http://localhost:3000',
// router: () => 'http://localhost:3001',
// },
// },
historyApiFallback: true,
},
output: {
path: path.resolve(__dirname, 'build'),
publicPath: '/',
},
resolve: {
extensions: ['*', '.js', '.ts', '.tsx', '.json', '.scss'],
fallback: {
crypto: require.resolve('crypto-browserify'),
assert: require.resolve('assert/'),
stream: require.resolve('stream-browserify'),
os: require.resolve('os-browserify/browser'),
fs: false,
dotenv: false,
},
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react'],
},
},
{
loader: 'ts-loader',
},
],
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react'],
},
},
{
test: /\.(png|jpg|gif|svg|ico)$/i,
use: [
{
loader: 'url-loader',
options: {
esModule: false,
limit: 8192,
},
},
],
},
{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
{
test: /\.(css)$/,
// exclude: /node_modules/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: 'public/index.html',
filename: 'index.html',
inlineSource: '.(js|css)',
}),
new MiniCssExtractPlugin({
filename: 'styles.css',
}),
// new HtmlWebpackInlineSourcePlugin(),
new webpack.DefinePlugin({
'process.env': {},
'process.argv': [],
'process.versions': {},
'process.versions.node': '"12"',
process: {
exit: '(() => {})',
browser: true,
versions: {},
cwd: '(() => "")',
},
}),
new webpack.ProvidePlugin({
Buffer: path.resolve(__dirname, 'externals', 'buffer.js'),
}),
new webpack.ContextReplacementPlugin(/\/keyv\//, (data) => {
delete data.dependencies[0].critical
return data
}),
new webpack.ContextReplacementPlugin(/\/maci\-crypto\//, (data) => {
delete data.dependencies[0].critical
return data
}),
],
optimization: {
// minimizer: [
// `...`,
// new CssMinimizerPlugin(),
// ],
},
}
What worked for me: Downgraded nanoid package to 3.3.4
OP posted it as a comment but, he fixed it by downgrading the nanoid
package from v4.0.0
I was facing the same issue and downgrading to the previous stable version 3.3.4
worked for me. Here is how I did it:
npm i [email protected]
Thanks OP!