jestjs / jest

Delightful JavaScript Testing.
https://jestjs.io
MIT License
44.22k stars 6.46k forks source link

[Bug]: import behavior has been broken for certain cases #12843

Open noomorph opened 2 years ago

noomorph commented 2 years ago

Version

28.1.0

Steps to reproduce

  1. Clone my repo from: https://github.com/noomorph/jest-import-issue
  2. Follow the steps in the README.

You'll see that a vanilla installation of Jest 28 behaves in a drastically different way when it comes to importing require('yargs/yargs').Parser.

Expected behavior

I'd expect Jest in both cases to find the exported function.

test('should import yargs/yargs Parser', () => {
  expect(require('yargs/yargs').Parser).toBeInstanceOf(Function);
});

Screen Shot 2022-05-13 at 17 37 04

Actual behavior

Jest 28 returns undefined on an attempt to require('yargs/yargs').Parser.

Screen Shot 2022-05-13 at 17 37 15

Additional context

I have to say that I can see node_modules/yargs/yargs there, a file without an extension. Inside it I see:

// TODO: consolidate on using a helpers file at some point in the future, which
// is the approach currently used to export Parser and applyExtends for ESM:
const {applyExtends, cjsPlatformShim, Parser, Yargs, processArgv} = require('./build/index.cjs')
Yargs.applyExtends = (config, cwd, mergeExtends) => {
  return applyExtends(config, cwd, mergeExtends, cjsPlatformShim)
}
Yargs.hideBin = processArgv.hideBin
Yargs.Parser = Parser
module.exports = Yargs

Maybe there's some problem with the package, with the way how it exports itself. But did you actually intend to introduce a breaking behavior with 28.x compared to 27.x?

Environment

System:
    OS: macOS 10.15.7
    CPU: (12) x64 Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz
  Binaries:
    Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node
    npm: 8.5.0 - ~/.nvm/versions/node/v16.14.2/bin/npm
  npmPackages:
    jest: ^28.1.0 => 28.1.0
noomorph commented 2 years ago

The issue is still relevant, just in case.

ghost commented 2 years ago

I have a similar issue. An npm package requires an script from another npm package :

require('three/examples/js/loaders/FontLoader.js');

The project itself has three as dependency. But somehow require can't find the script in the three npm package but three itself. I get the error:

 Cannot find module 'three/examples/js/loaders/FontLoader.js' from 'node_modules/@wmc/zk-web3d/dist/es5/services/FontManager.js'

My current workaround is to set a moduleNameMapper for the script in the jest.config.js

module.exports = {
   ...
   moduleNameMapper: {
        ...
        'three/examples/js/loaders/FontLoader.js': 'node_modules/three/examples/js/loaders/FontLoader.js'
    }
}

It worked with jest 27.5.1 but broke after updated to 28.1.0.

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.

noomorph commented 2 years ago

Jest 28.1.3 fails at this example just as it did the first day. 🤷‍♂️

The issue is relevant.

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.

SimenB commented 2 years ago

This is a bug in resolve.exports (the lib we use to resolve exports, which shipped in Jest 28).

const pkg = require('yargs/package.json')

const { resolve } = require('resolve.exports');

console.log(resolve(pkg, 'yargs', { conditions: ['require'], unsafe: true }));
console.log(require.resolve('yargs/yargs'))

Possibly https://github.com/lukeed/resolve.exports/issues/17?

unional commented 1 year ago

Don't know if this is a good place, I notice if the dependency is:

{
  "type": "module",
  "exports": "./index.mjs",
  "main": "./index.js"
}

jest will load ./index.mjs correctly. But if the dependency is:

{
  "type" : "module",
  "exports": {
    "import": "./index.mjs",
    "require": "./index.js"
  }
}

jest will load ./index.js instead.

catalinandreipreda commented 5 months ago

It seems I am unable to update another dependency I have because of this bug or jest-cli simply expects an older version of yargs then my updated yarn.lock

Error [ERR_REQUIRE_ESM]: require() of ES Module /home/catalin/Code-WSL/creativeonl/node_modules/string-width/index.js from /home/catalin/Code-WSL/creativeonl/node_modules/cliui/build/index.cjs not supported. Instead change the require of index.js in /home/catalin/Code-WSL/creativeonl/node_modules/cliui/build/index.cjs to a dynamic import() which is available in all CommonJS modules. at Object. (/home/catalin/Code-WSL/creativeonl/node_modules/cliui/build/index.cjs:291:21) at Object. (/home/catalin/Code-WSL/creativeonl/node_modules/yargs/build/index.cjs:1:60678) at Object. (/home/catalin/Code-WSL/creativeonl/node_modules/yargs/index.cjs:5:30) at _yargs (/home/catalin/Code-WSL/creativeonl/node_modules/jest-cli/build/run.js:30:39) at buildArgv (/home/catalin/Code-WSL/creativeonl/node_modules/jest-cli/build/run.js:149:26) at Object.run (/home/catalin/Code-WSL/creativeonl/node_modules/jest-cli/build/run.js:124:24) at Object. (/home/catalin/Code-WSL/creativeonl/node_modules/jest-cli/bin/jest.js:16:17) at Object. (/home/catalin/Code-WSL/creativeonl/node_modules/jest/bin/jest.js:12:3)

My upgrade has a sub dependency resulting in this lock change

image