Taylor Austin
Taylor Austin

Reputation: 6027

Nextjs & Jest transform/transformIgnorePatterns not working with esm modules

I've done a good amount of research on this and have found a decent amount of solutions. I have found what feels like a workaround and would like to get the transform and transformIgnorePatterns working. It seems the only thing I can get working however is to manually add some mock modules inside of my __mocks__ folder.

Not sure if this is due to using Nextjs with Jest or not?

Here is my jest.config.js

const nextJest = require("next/jest");

const esModules = ["react-markdown", "rehype-raw", "remark-gfm"].join("|");

const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: "./",
});

// Add any custom config to be passed to Jest
const customJestConfig = {
  setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
  moduleNameMapper: {
    // Handle module aliases (this will be automatically configured for you soon)
    "^@/components/(.*)$": "<rootDir>/components/$1",

    "^@/pages/(.*)$": "<rootDir>/pages/$1",
  },
  testEnvironment: "jest-environment-jsdom",
  transform: {
    [`(${esModules}).+\\.js$`]: "babel-jest",
  },
  transformIgnorePatterns: [
    `[/\\\\]node_modules[/\\\\](?!${esModules}).+\\.(js|jsx|mjs|cjs|ts|tsx)$`,
  ],
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);

I have read that I will need a babel.config.js as well. Here is that file:

module.exports = {
  presets: ["next/babel", "@babel/preset-env"],
};

Upvotes: 8

Views: 6644

Answers (2)

Zach Olivare
Zach Olivare

Reputation: 4161

I had this problem specifically with jest and react-dnd as reported here.

I used the same solution as @Mark Nunes above, but tidied up a bit:

// jest.config.js
const nextJest = require('next/jest')

const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: './',
})

const customJestConfig = {
  // You can add other jest config overrides here

  testPathIgnorePatterns: ['/node_modules/'],

  // DON'T SET THIS HERE - it's overridden below
  transformIgnorePatterns: [],
}

module.exports = async function() {
  const makeConfig = await createJestConfig(customJestConfig)
  const finalJestConfig = await makeConfig()

  // This replaces the default of '/node_modules/'
  finalJestConfig.transformIgnorePatterns[0] =
    '/node_modules/(?!@react-dnd|react-dnd|dnd-core|react-dnd-html5-backend/)'

  return finalJestConfig
}

Upvotes: 3

Mark Nunes
Mark Nunes

Reputation: 985

Here is a solution in case someone runs into this same issue but is using NextJs 12.2, next/jest and Jest 28.

Jest provides some experimental support for ECMAScript Modules (ESM) but "node_modules" are not transpiled by next/jest yet.

So we need to use transformIgnorePatterns to prevent the ESM files from being transformed.

The default configuration for changing transformIgnorePatterns is overwritten by next/jest see below the solution for this.

// jest.config.js
const nextJest = require('next/jest')

const createJestConfig = nextJest({
  // Path to Next.js app to load next.config.js
  dir: './'
})

/** @type {import('@jest/types').Config.InitialOptions} */
const customJestConfig = {
  /**
   * Custom config goes here, I am not adding it to keep this example simple.
   * See next/jest examples for more information.
   */
 }

module.exports = async () => ({
  ...(await createJestConfig(customJestConfig)()),
  transformIgnorePatterns: [
    // The regex below is just a guess, you might tweak it
    'node_modules/(?!(react-markdown|rehype-raw|remark-gfm)/)',
  ]
})

I created a repository for a full reference of the necessary setup for a case that was using swiper/react. https://github.com/markcnunes/with-jest-and-esm

Have in mind this setup might have to change for future Next.js / next/js versions but just sharing this approach in case this is useful for other people using this same setup.

I also used this answer to another question in case you are looking for solutions related to swiper/react.

Upvotes: 21

Related Questions