unjs/jiti

Regression when `require(extensionless-ts)` from JS

webpro opened this issue · 5 comments

Environment

Regression when upgrading from Jiti v1 to Jiti v2.

Can reproduce in Node.js 18 and 22.

Reproduction

See https://stackblitz.com/edit/stackblitz-starters-earn9d

Initially you can ignore client and shared folders, that holds the original dependency chain in the freeCodeCamp repo where Knip is used and gatsby-node.js is loaded with jiti.import (Jiti v2). I minimized that chain for a minimal repro to just two files: index.js and req-ts.ts.

Can see the issue here (require(extensionless-ts)) and maybe it wasn't supposed to work in the first place, but this loads without issues in Jiti v1:

$ npx jiti@^1 index.js

Yet with v2 this gives an error:

$ npx jiti@^2 index.js
Error: Cannot find module './req-ts'
Require stack:
- /Users/lars/p/knip/jiti-repro/index.js

Describe the bug

With Jiti v1, Knip was loading this file without issues using the jitiCJS loader as created here: https://github.com/webpro-nl/knip/blob/b1cf45a9c82f16e83618e7841c2ec850d9b9d781/packages/knip/src/util/jiti.ts#L8-L21 (i.e. esmResolve: false, extensions: [] and interopDefault: true).

I think it's a regression, but maybe I'm missing some config.

Additional context

Didn't yet look into how in the original context Gatsby loads this, first wanted to check whether Jiti v2 is supposed to support this at all in the first place, or whether it's considered a breaking change.

Logs

No response

pi0 commented

Hi dear @webpro thanks for spending time reproducing and explaining.

Using JITI_DEBUG=1, shows the situation:

image

The index.js passes all checks to be considered as a valid CommonJS module therefore jiti will try to import it natively.

It was the same in jiti v1 but jiti has a "fallback" mode that if prediction fails (native import fails), it tries again with transpile mode:

image

Jiti v2 also has the same fallback mode but it is not working in async context.

Looking for a solution.

pi0 commented

I think should be fixed in 2.3.2. LMK if any other issues.

That was fast!

Looks like it's partially fixed. No more exception thrown. However, if I load the same file programmatically, the return value of jiti.import seems undefined.

I have updated the SB with program.js that can be run using node program.js.

Oh I realize I've added "type": "module" to package.json which perhaps makes this a different problem. Here's the debug output:

❯ JITI_DEBUG=1 node program.js
[jiti] [init] version: 2.3.2 module-cache: true fs-cache: true interop-defaults: true
[jiti] [native] [import] ./index.js
[jiti] Native import error: {}
[jiti] [fallback] ./index.js
[jiti] [cache] [miss] ./index.js
[jiti] [cache] [store] ./index.js ~> ./node_modules/.cache/jiti/stackblitz-starters-earn9d-index.1f56f7f2.mjs
[jiti] [transpile] [esm] ./index.js (11.535ms)
[jiti] [cache] [miss] ./req-ts.ts
[jiti] [cache] [store] ./req-ts.ts ~> ./node_modules/.cache/jiti/stackblitz-starters-earn9d-req-ts.6a2007e2.cjs
[jiti] [transpile] [cjs] ./req-ts.ts (10.26ms)
undefined

CommonJS also gives undefined tho:

const { createJiti } = require('jiti');
const jiti = createJiti();
jiti.import('./index.js', { default: true }).then(console.log);