reactjsjestjsts-jestbabel-jest

Jest Configuration Error: Cannot Use Import Statement Outside a Module in React and TypeScript Project


I'm encountering issues when running Jest in my React and TypeScript project. The errors I'm facing are related to ES module imports.

Here are the errors i get:

C:\projects\my-project\web\node_modules\swiper\react\swiper-react.js:13
    import { Swiper } from './swiper.js';
    SyntaxError: Cannot use import statement outside a module

**or**

C:\projects\my-project\web\node_modules\ssr-window\ssr-window.esm.js:148
    export { extend, getDocument, getWindow, ssrDocument, ssrWindow };
    ^^^^^^

    SyntaxError: Unexpected token 'export'

Package.json

{
  "name": "web",
  "version": "0.1.0",
  "private": true,
  "type": "commonjs",
  "dependencies": {
    "@reduxjs/toolkit": "^1.8.3",
    "@tasoskakour/react-use-oauth2": "^2.0.1",
    "@types/node": "^12.19.12",
    "axios": "^0.21.0",
    "dayjs": "^1.9.7",
    "jwt-decode": "^3.1.2",
    "lib": "file:../lib",
    "react": "^18.2.0",
    "react-datepicker": "^4.8.0",
    "react-dom": "^18.2.0",
    "react-range": "^1.8.14",
    "react-redux": "^7.2.8",
    "react-router-dom": "^5.2.0",
    "react-scripts": "^5.0.1",
    "react-spring": "^9.5.2",
    "react-toastify": "^10.0.5",
    "redux": "^4.2.0",
    "redux-devtools-extension": "^2.13.9",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.4.1",
    "sass": "^1.30.0",
    "swiper": "^8.4.6",
    "typescript": "^4.3.5",
    "web-vitals": "^0.2.4"
  },
  "devDependencies": {
    "@babel/core": "^7.24.7",
    "@babel/plugin-transform-modules-commonjs": "^7.24.7",
    "@babel/preset-env": "^7.24.7",
    "@testing-library/dom": "^10.1.0",
    "@testing-library/jest-dom": "^6.4.6",
    "@testing-library/react": "^16.0.0",
    "@testing-library/user-event": "^14.5.2",
    "@types/jest": "^29.5.12",
    "@types/react": "^18.3.3",
    "@types/react-datepicker": "^4.4.2",
    "@types/react-dom": "^18.3.0",
    "@types/react-redux": "^7.1.24",
    "@types/react-router-dom": "^5.3.3",
    "@typescript-eslint/eslint-plugin": "^5.31.0",
    "@typescript-eslint/parser": "^5.31.0",
    "babel-jest": "^29.7.0",
    "customize-cra": "^1.0.0",
    "eslint": "^8.20.0",
    "eslint-config-prettier": "^7.0.0",
    "eslint-plugin-prettier": "^3.3.0",
    "jest": "^29.7.0",
    "jest-environment-jsdom": "^29.7.0",
    "jest-transform-stub": "^2.0.0",
    "prettier": "^2.2.1",
    "react-app-rewired": "^2.1.8",
    "ts-jest": "^29.1.5",
    "ts-node": "^10.9.2"
  },
  "resolutions": {
    "@types/react": "^17.0.38"
  },
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "jest --verbose",
    "test2": "react-app-rewired test",
    "eject": "react-scripts eject"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "jest": {
    "preset": "ts-jest",
    "transform": {
      "^.+\\.(ts|tsx|js|jsx)$": "ts-jest"
    },
    "transformIgnorePatterns": [
      "/node_modules/(?!swiper|lib|swiper/react)"
    ],
    "testEnvironment": "jsdom",
    "clearMocks": true,
    "collectCoverage": true,
    "coverageDirectory": "coverage",
    "moduleNameMapper": {
      "^@reducers/(.*)$": "<rootDir>/src/redux/reducers/$1",
      "^@actions/(.*)$": "<rootDir>/src/redux/actions/$1",
      "^@selectors/(.*)$": "<rootDir>/src/redux/selectors/$1",
      "^@pages/(.*)$": "<rootDir>/src/pages/$1",
      "^@components/(.*)$": "<rootDir>/src/components/$1",
      "^@routes/(.*)$": "<rootDir>/src/routes/$1",
      "^@styles/(.*)$": "<rootDir>/src/_styles/$1",
      "^@content/(.*)$": "<rootDir>/src/_content/$1",
      "^@config/(.*)$": "<rootDir>/src/config/$1",
      "^@hooks/(.*)$": "<rootDir>/src/hooks/$1",
      "^@constants/(.*)$": "<rootDir>/src/constants/$1",
      "^.+.(css|styl|less|sass|scss|png|jpg|jpeg|ttf|woff|woff2)$": "jest-transform-stub"
    }
  }
}

tsconfig.json

{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {
    "module": "commonjs", // Ensure this is set to 'commonjs'
    "target": "ES2015",
    "lib": ["dom", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ],
  "exclude": [
    "node_modules",
    "dist"
  ]
}

.babelrc

{
    "presets": [
      "@babel/preset-env",
      "@babel/preset-react",
      "@babel/preset-typescript"
    ],
    "plugins": [
        "@babel/plugin-transform-modules-commonjs"
    ],
    "env": {
      "test": {
        "plugins": [
          "@babel/plugin-transform-modules-commonjs"
        ]
      }
    }
  }
  

Most of the errors are related to libraries from node_modules. I tried to add the modules in transformIgnorePatterns, but it's not working. messed around with tsconfig.json and .babelrc configs but still coudn't make the error go.


Solution

  • Adding to transformIgnorePatterns should work, as you said.

    I noticed that you're using Windows. Writing a Windows-compatible transformIgnorePatterns is trickier; you'll want to handle both backslashes (as used on Windows) and forward slashes (for the benefit of any Mac or Linux colleagues, and your CI may run Linux), and backslashes need escaping when used in JS strings. To transform swiper and my-other-dep, Your transformIgnorePatterns should look something like this.

      transformIgnorePatterns: [
        '[/\\\\]node_modules[/\\\\](?!swiper[/\\\\]|my-other-dep[/\\\\])',
      ],