firsttris / vscode-jest-runner

Simple way to run or debug one or more tests from context menu, codelens or command plalette
https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner
MIT License
265 stars 124 forks source link

Jest fails to parse .ts config file with absolute path #341

Closed Bjoren closed 6 months ago

Bjoren commented 9 months ago

Hi!

When using Jest Runner to execute my Jest tests in an ES2022 TypeScript environment with ECMA-style modules, Jest failes to parse the configuration file. I'm guessing it's because Jest neglects to transform CommonJS into ECMA for some contextual reason.

Jest Runner executes: node "node_modules/jest/bin/jest.js" "c:<absolute path>/<some test file>.spec.ts" -c "c:/<absolute path>/jest.config.ts" -t "<some test name>"

which produces:

Error: Jest: Failed to parse the TypeScript config file c:/<absolute path>/jest.config.ts
   Error: Must use import to load ES Module: c:\<absolute path>\jest.config.ts
require() of ES modules is not supported.
require() of c:\<absolute path>\jest.config.ts from C:\<absolute path>\node_modules\.pnpm\jest-config@29.7.0_@types+node@20.8.10_ts-node@10.9.1\node_modules\jest-config\build\readConfigFileAndSetRootDir.js is an ES module file as it is a .ts file whose nearest parent package.json contains "type": "module" which defines all .ts files in that package scope as ES modules.
Instead change the requiring code to use import(), or remove "type": "module" from c:\<absolute path>\package.json.

    at readConfigFileAndSetRootDir (<...>\node_modules\jest-config\build\readConfigFileAndSetRootDir.js:116:13)
    at async readInitialOptions (<...>\node_modules\jest-config\build\index.js:392:15)
    at async readConfig (<...>\node_modules\jest-config\build\index.js:147:48)
    at async readConfigs (<...>\node_modules\jest-config\build\index.js:424:26)
    at async runCLI (<...>\node_modules\@jest\core\build\cli\index.js:151:59)
    at async Object.run (<...>\node_modules\jest-cli\build\run.js:130:37)

However, if I modify the command to either use the relative path to the config file, or leave it out altogether and let Jest resolve the config location itself, it runs without error.

These work: node "node_modules/jest/bin/jest.js" "c:<absolute path>/<some test file>.spec.ts" -c "jest.config.ts" -t "<some test name>" node "node_modules/jest/bin/jest.js" "c:<absolute path>/<some test file>.spec.ts" -t "<some test name>"

Can I set up Jest Runner to behave in this way, somehow? Is there an alternative solution I am not aware of, or am I doing something wrong in my repo?

firsttris commented 9 months ago

can you also post your jest.config.ts

Bjoren commented 9 months ago

Sure!

import type { Config } from '@jest/types'

export default async (): Promise<Config.InitialOptions> => {
  return {
    extensionsToTreatAsEsm: [".ts"],
    globals: {
      "ts-jest": {
        useESM: true
      }
    },

    verbose: true,
    modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
    globalSetup: './src/pre-test.ts'
  }
}
firsttris commented 6 months ago

The error message is indicating that your jest.config.ts file is being treated as an ES module because it's a .ts file and the nearest parent package.json contains "type": "module". However, Jest is trying to use require() to load it, which is not supported for ES modules.

To fix this issue, you have two options:

  1. Change the jest.config.ts to a CommonJS module by renaming it to jest.config.js and using module.exports instead of export default.

  2. Remove "type": "module" from your package.json file. This will make Node.js treat .ts files as CommonJS modules by default.

Here's how you can do the first option:

// jest.config.js
module.exports = {
  // your jest configuration
};

And here's how you can do the second option:

// package.json
{
  "name": "your-package-name",
  "version": "1.0.0",
  // remove "type": "module"
  // other package.json properties
}

Please choose the option that best fits your project's needs.

firsttris commented 6 months ago

i closed this issue because i think its related to your config, not to the extension. if you need more help just re-open or reply.