9

I've reached a dead end trying to fix this issue. I am using the following TypeScript configuration:

{
    "compilerOptions": {
        "module": "es2022",
        "moduleResolution": "nodenext",
        "target": "es2017",
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true,
        "noImplicitAny": true,
        "outDir": "./dist",
        "rootDir": "./src",
        "typeRoots": [
            "./src/types", "./node_modules/@types"],
        "allowJs": true,
        "strictFunctionTypes": true,
        "noImplicitReturns": true
    },
    "include": ["./src/**/*"],
    "exclude": ["node_modules"],
    "ts-node": {
        "esm": true,
        "experimentalSpecifierResolution": true
    }
}

As you see the moduleResolution is set to nodenext, and because of that I have to explicitly add a file extension when importing, like this: import ServerError from '../models/Errors/ServerError.js';. Otherwise, I get an error that the module was not found.

Everything is working fine, but when I launch my tests I get an error: Cannot find module '../models/Errors/ServerError.js' from '../src/services/usersService.ts'. So basically jest is trying to find the file ServerError.js, but it does not exist, because all files have a .ts extension, so it should be ServerError.ts. If I try to change .js to .ts in my files I also will get an error.

I can't finish my task because of this problem, so I would appreciate any help.

6 Answers 6

26

Finally, I've managed to solve this problem after doing some research and updating my jest config file.

/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
import type { Config } from 'jest';

const config: Config = {
    transform: {
        '\\.[jt]sx?$': 'ts-jest'
    },
    globals: {
        'ts-jest': {
            useESM: true
        }
    },
    moduleNameMapper: {
        '(.+)\\.js': '$1'
    },
    extensionsToTreatAsEsm: ['.ts']
};

With this configuration, everything is working fine. I hope that it will help somebody.

Sign up to request clarification or add additional context in comments.

3 Comments

I find out that configuring ts-jest through globals property is outdated. Instead, you should remove 'ts-jest' from globals and write the following to the transform property: transform: {'\\.[jt]sx?$': ['ts-jest', { useESM: true }] }. Everything else is the same.
Related issue: github.com/kulshekhar/ts-jest/issues/1057 I couldn't solve this when not using "ts-jest" though
I guess as of now, the only essential things from the config above are transform and moduleNameMapper. At least that is what enough for my case
22

For me this did the trick:

  "moduleNameMapper": {
    "^(\\.\\.?\\/.+)\\.js$": "$1",
  },

(Adapted from https://github.com/kulshekhar/ts-jest/issues/1057#issuecomment-1441733977)

2 Comments

This is enough with the recommended transform from the ts-jest docs: "^.+\\.tsx?$": ["ts-jest", ....] . It isn't needed to set moduleFileExtensions or extensionsToTreatAsEsm.
very similar, for me it was : moduleNameMapper: { '(.+)\\.js': '$1' }
4

I added only moduleNameMapper key in my case, this solved the issue for me. I've been using ts-jest/presets/default-esm preset.

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: "ts-jest/presets/default-esm",
  moduleNameMapper: {
    "(.+)\\.js": "$1",
  },
};

1 Comment

Perfect, thank you! Additionally, in my jest test files themselves I needed to add a new import import { jest } from '@jest/globals' per stackoverflow.com/a/65203348/470818 . Though stackoverflow.com/a/74802002/470818 says there may be a way to do it without importing jest globally.
1

I solve the problem with add a config moduleFileExtensions setting in jest.config.json;

{
    ....
    "moduleFileExtensions": ["ts", "js"],
    ....
}

Comments

1

This can be fixed by using jest-ts-webcompat-resolver npm package.

npm i jest-ts-webcompat-resolver -D

In your jest.config.ts add:

"resolver": "jest-ts-webcompat-resolver"

Comments

1

What worked for me was a mix of the accepted answer and the settings from TS-Jest documentation.

const { defaultsESM: tsjPreset } = require('ts-jest/presets');

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  ...tsjPreset,
moduleNameMapper: { '^(\\.|\\.\\.)\\/(.+)\\.js': '$1/$2' },

  // ....

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.