jestjs - Jest, ts-jest, typescript med ES Modules import: kan inte hitta modul


Jag har problem med att få Jest att arbeta med ett TypeScript-projekt som använder ES-moduler med syntaxen import. Mitt projekt skrevs ursprungligen för CommonJS, och Jest-tester gick utan problem. Men sedan bestämde jag mig för att byta till ES-moduler (i inlärningssyfte), Jest är inte nöjd ヽ(`Д´)ノ Verktygen jag använder: TypeScript, Jest, ts-jest

Problemet startar med import-syntaxen.

Följande är koder som jag hade försökt.

//  projectRoot/src/app.ts

export default someFunction = (): void => {
   // some code
}

Om

// projectRoot/__tests__/app.test.ts

import someFunction from '../src/app';   // without file extension

/* This execute perfectly fine */

Men

// projectRoot/__tests__/app.test.ts

import someFunction from '../src/app.ts'   // with .ts

/*
● Test suite failed to run

   __tests__/app.test.ts:1:25 - error TS2691: An import path cannot end with a '.ts' extension. Consider importing '../src/app' instead.

    1 import information from '../src/app.ts';
*/

Och

// projectRoot/__tests__/app.test.ts

import someFunction from '../src/app.js';   // with .js

/*
● Test suite failed to run

    Cannot find module '../src/app.js' from '__tests__/app.test.ts'
*/

Som ovan exempel, jest (eller kanske ts-jest?) är inte nöjd om jag importerar modulen med filändelse (vilket är ett måste för ES-moduler). Jag gjorde lite sökande online, men det verkar som om jest-dokumentationen inte är särskilt stödjande för ES-moduler. Samma gäller för ts-jest enligt denna läsning.

Min projektstruktur:

/projectRoot
 ├── /src/app.ts
 ├── /__tests__/app.test.ts

Inuti filen package.json finns värdet "type": "module"

tsconfig.json:

{
  "compilerOptions": {
     "target": "ES2015",
     "module": "ESNEXT",
     "outDir": "./build",
     "strict": true,
     "moduleResolution": "node",
     "esModuleInterop": true,
     "skipLibCheck": true,
     "forceConsistentCasingInFileNames": true
  },
  "include": ["./src"],
  "exclude": ["node_modules", "**/*.test.ts"]
}

jest.config.js

export default {
    "roots": [
      //"<rootDir>/src"
      "<rootDir>"
    ],
    "testMatch": [
      "**/__tests__/**/*.+(ts|tsx|js)",
      "**/?(*.)+(spec|test).+(ts|tsx|js)"
    ],
    "transform": {
      "^.+\\.(ts|tsx)$": "ts-jest"
    },
    "preset": "ts-jest",
    "testEnvironment": 'node'
  }

Var snäll och hjälp. Tack.

Svar #1

Med importen nedan

// projectRoot/__tests__/app.test.ts

import someFunction from '../src/app.js';   // with .js

ts-jest kan konfigureras för att använda detta med följande konfigurationer. I filen jest.config.js lägg till följande:

module.exports = {
  //... // your previous configurations
  extensionsToTreatAsEsm: ['.ts'],
  globals: {
    'ts-jest': {
      //... // your other configurations here
      useESM: true,
    },
  },
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',
  }

Källan till denna konfiguration kan hittas på ts-jests dokumentsida: ESM-Support

Några av mina exempel på kod är nedan:

// components_ts.ts
export add(x: number, y: number): number {
    return x + y;
}
// render_ts.ts
import * as ComponentsTS from './components_ts.js'; // <-- Extension is JS

export function addedNumbers(): number {
    let addedNumbers: number = ComponentsTS.add(1, 2);
    return addedNumbers;
}
// render_ts.test.ts
import * as RenderTS from '../ts_files/render_ts';

it ('Test addNumbers function', () => {
    expect(RenderTS.addedNumbers()).toBe(3);
});

Kör detta med npm jest

Relaterade artiklar