Búsqueda de sitios web

node.js - Jest Typescript con ES Module en node_modules error - Debe usar import para cargar ES Module:


Estoy tratando de escribir una prueba sencilla con jest para un paquete de terceros que estamos usando y que solo exporta un módulo ES. Es un envoltorio alrededor de un servidor http.

Aquí hay un repositorio de prueba que configuré (solo ejecuta yarn && yarn jest para reproducirlo): https://github.com/jamesopti/hocuspocus-testing

No importa con qué configuración experimente, todavía obtengo este error al intentar ejecutarlo:

 Must use import to load ES Module: /Users/j/hocuspocus-testing/node_modules/@hocuspocus/server/dist/hocuspocus-server.esm.js

    > 1 | import { Server, Hocuspocus } from '@hocuspocus/server'
        | ^
      2 | import * as request from 'supertest'
      3 |
      4 | describe('Server (e2e)', () => {

Cosas que ya he intentado:

  • Las instrucciones de Jest sobre módulos ES: https://jestjs.io/docs/ecmascript-modules

  • En la configuración de Jest usando transformIgnorePatterns

    • transformIgnorePatterns: ['node_modules/(?!@hocuspocus/)']
  • Usando Babel a través de babel-jest

    • modificando la configuración de transformación en Jest como '^.+\.jsx?$': 'babel-jest', '^.+\.tsx?$': 'ts-jest'

    • Me encontré con el error Parece que estás usando un archivo de configuración de módulo ECMAScript nativo, que solo es compatible al ejecutar Babel de forma asincrónica.

    • Usando .babel.config.js en lugar de .babelrc.js

¿Alguna idea de qué me estoy perdiendo aquí? Pensé que esto sería sencillo

[EDIT 1] - Se añadió tsconfig.json y un archivo src/index.ts funcional al repositorio de ejemplo.

Respuesta #1

Así que, para cualquiera que todavía esté usando esto, la configuración de ESM se explica en esta sección de la documentación:

https://kulshekhar.github.io/ts-jest/docs/guides/esm-support

{
  // [...]
  "jest": {
    "extensionsToTreatAsEsm": [".ts"],
    "globals": {
      "ts-jest": {
        "useESM": true
      }
    }
  }
}

Respuesta #2

ENE 2023: ES2022, TypeScript 4.9.4, jest 29.3.1, ts-jest 29.0.3 FEB 2024: Se modificó la expresión regular del archivo de transformación según el comentario de @vick

Esto es lo que funcionó para mí, después de 2 horas de frustración. Usé esta configuración en jest.config.ts:

import type { JestConfigWithTsJest } from 'ts-jest'

const config: JestConfigWithTsJest = {
  extensionsToTreatAsEsm: ['.ts'],
  verbose: true,
  preset: 'ts-jest/presets/default-esm',
  testEnvironment: 'node',
  transform: {
    '^.+\\.tsx?$': ['ts-jest', { useESM: true }]
  },
  testPathIgnorePatterns: ['./dist']
}

export default config

Cambia el script test en package.json a:

Yo uso pnpm. Cambia a npx jest con npm, o yarn exec con yarn

...
"scripts": {
  ...
  "test": "NODE_OPTIONS=--experimental-vm-modules pnpm exec jest",
  ...
}
...

tsconfig.json:

{
  "compilerOptions": {
    "rootDirs": ["src"],
    "outDir": "dist",
    "lib": ["ES2022"],
    "target": "ES2022",
    "module": "ES2022",
    "composite": true,
    "moduleResolution": "node",
    "declaration": true,
    "declarationMap": true,
    "incremental": true,
    "esModuleInterop": true,
    "types": ["jest", "node", "@types/jest"],
    "sourceMap": true
  },
  "ts-node": {
    "esm": true,
    "experimentalSpecifierResolution": "node"
  },
  "include": ["./src/**/*", "./tests/**/*"]
}

Consulta esta documentación (bastante confusa) como referencia: https://kulshekhar.github.io/ts-jest/docs/guides/esm-support/

Respuesta #3

Aunque me disguste dar una respuesta del tipo 'usa otra cosa', lo voy a hacer, aunque pueda que no responda directamente a la pregunta original.

Sin embargo, responde a la pregunta "¿Cómo puedo facilitar la prueba de mis archivos TypeScript que tienen dependencias ESM, usando la sintaxis de Jest?"

Después de probar con varias opciones de jest.config.js, tomando ideas de algunas de estas respuestas, finalmente simplemente hice:

npm install -D vitest       

... y, todo simplemente funcionó. Sin archivo jest.config.js. Sin complicarse con otras dependencias.

El único cambio que tuve que hacer fue importar algunas funciones relacionadas con pruebas que no tienes que importar con Jest:

import { expect, describe, it } from "vitest";

Aparte de esto, es fácil olvidar que no estoy simplemente usando Jest.

Más detalles aquí: https://vitest.dev/guide/.

EDICIÓN: Como se sugiere en un comentario útil, puedes configurar una opción para que no sea necesario importar expect/describe/it.

Vea aquí los detalles sobre cómo usar globals: true: https://vitest.dev/config/#globals.

Artículos relacionados