kulshekhar / ts-jest

A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript.

Home Page:https://kulshekhar.github.io/ts-jest

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug]: global-setup and esm do not work when importing relatively

hasezoey opened this issue · comments

Version

29.1.0

Steps to reproduce

  1. clone https://github.com/hasezoey/ts-jest-esm-globalsetup-issue
  2. install all packages (yarn install)
  3. run yarn jest
  4. observe error

Expected behavior

i expect the import to work like in commonjs

Actual behavior

error about not being able to import the given file

Debug log

TS_JEST_LOG=ts-jest.log yarn jest
yarn run v1.22.19
$ /mnt/projects/nodejs/ts-jest_test/node_modules/.bin/jest
Error: Jest: Got error running globalSetup - /mnt/projects/nodejs/ts-jest_test/test/globalSetup.ts, reason: Cannot find module '../src/somefile.js'
Require stack:
- /mnt/projects/nodejs/ts-jest_test/test/globalSetup.ts
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-util/build/requireOrImportModule.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-util/build/index.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-config/build/getCacheDirectory.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-config/build/Defaults.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-config/build/normalize.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-config/build/index.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-cli/build/init/index.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-cli/build/run.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-cli/build/index.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest-cli/bin/jest.js
- /mnt/projects/nodejs/ts-jest_test/node_modules/jest/bin/jest.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1090:15)
    at Module._load (node:internal/modules/cjs/loader:934:27)
    at Module.require (node:internal/modules/cjs/loader:1157:19)
    at require (node:internal/modules/helpers:119:18)
    at Object.<anonymous> (/mnt/projects/nodejs/ts-jest_test/test/globalSetup.ts:1:1)
    at Module._compile (node:internal/modules/cjs/loader:1275:14)
    at Module._compile (/mnt/projects/nodejs/ts-jest_test/node_modules/pirates/lib/index.js:136:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1329:10)
    at Object.newLoader (/mnt/projects/nodejs/ts-jest_test/node_modules/pirates/lib/index.js:141:7)
    at Module.load (node:internal/modules/cjs/loader:1133:32)
error Command failed with exit code 1.

Additional context

already tried to use ts-jest-resolver as a resolver and also tried using preset ts-jest/presets/default-esm and setting the options manually, also tried various options from ESM Support

Environment

System:
    OS: Linux 6.3 Manjaro Linux
    CPU: (16) x64 AMD Ryzen 7 5800X 8-Core Processor
  Binaries:
    Node: 19.9.0 - /tmp/yarn--1683548400265-0.7148494764630906/node
    Yarn: 1.22.19 - /tmp/yarn--1683548400265-0.7148494764630906/yarn
    npm: 5.1.0 - /mnt/projects/nodejs/ts-jest_test/node_modules/.bin/npm
  npmPackages:
    jest: ^29.5.0 => 29.5.0

Worked for me adding compilerOptions: "allowImportingTsExtensions": true with "noEmit": true (that is required for the first one to work). Then importing from ../src/somefile.ts works.

In real world allowImportingTsExtensions should live in some tsconfig.test.json. Or so.

Or without any changes in tsconfig.json, but import from ../src/somefile.

(Indeed buggy. That should throw an error.)

but import from ../src/somefile.

that is not possible, then typescript complains that the extension is missing in esm

commented

This is not something ts-jest can solve. The error was thrown out before reaching transforming step. The globalSetup file never reaches process method of the transformer.

Worked for me adding compilerOptions: "allowImportingTsExtensions": true with "noEmit": true (that is required for the first one to work). Then importing from ../src/somefile.ts works.

In real world allowImportingTsExtensions should live in some tsconfig.test.json. Or so.

@mrazauskas But it wont compile with noEmit (or the --noEmit flag) set to true. Furthermore, if i create one tsconig.json with ... "allowImportingTsExtensions": true, "noEmit": true ..., and a tsconfig.build.json with

{
    "extends": "./tsconfig.json",
    "compilerOptions": {
        "allowImportingTsExtensions": false,
        "noEmit": false
    },
    "include": ["src/**/*"],
    "exclude": ["tests/**/*"]
}

It still doesnt compile with the tsconfig.build.json because i have imported everything like import { foo } from "bar.ts" (see my issue #4162) to satisfy jest/ts-jest. So practically i need two codebases, one with everything imported as import { foo } from "bar.ts" for testing and one with everything imported as import { foo } from "bar" to actually compile it. maybe Babel could help to add the extensions before running jest or ts-jest. I am not a babel wizard, maybe somebody could help me. This issue rendered my codebase useless for production and @kulshekhar isnt responding.
Any help is highly appreciated

EDIT: I found https://www.npmjs.com/package/babel-plugin-add-import-extension which could be integrated into ts-jest as a starting point.

I don't have references handy but for server-side TS code I think the consensus is now to add .js extensions to relative imports. It's a hassle and I'm not sure the tooling is totally there yet. I filed #4013 to document this approach but I haven't had time to put together a PR -- I just got back to working on related projects this week.

but import from ../src/somefile.

that is not possible, then typescript complains that the extension is missing in esm

Try with "moduleResolution": "node10" 🙄 Works just great with "target"/"module": "esnext" - only looks dumb but hey, whatever makes TS spit out the actual JavaScript...

I think the consensus is now to add .js extensions to relative imports. It's a hassle and I'm not sure the tooling is totally there yet.

I think "consensus" is not the right word here. Sure, let's import non-existent files - that makes perfect sense...

Anyway, I'm experiencing a similar issue, not sure if related but here goes:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Jest: Got error running globalSetup - \
/path/to/the/project/test/globalSetup.ts, reason: Unknown file extension ".ts" for \
/path/to/the/project/test/globalSetup.ts

It just started happening, and it doesn't provide a trace or anything. git bisected it to where I'm adding a file to the project that doesn't have anything to do with the tests or test setup.

So far I've narrowed down to: if I comment out a certain function call in the function exported by globalSetup, Jest remembers it's actually configured to support TS, if I uncomment it - we're back in the middle of nowhere. Is it doing tree-shaking ffs?

Of course, I tried digging through node_modules to trace the control flow, reached the point where it uses pirates to hook require, and threw my hands up.