jestjs / jest

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

Pure ESM module with only `exports`, no `main` not resolved ("Cannot find module") #11373

Closed akx closed 3 years ago

akx commented 3 years ago

🐛 Bug Report

I'm using the is-what module in my project. It was recently updated to be a pure ESM module as championed by Sindre (see https://blog.sindresorhus.com/get-ready-for-esm-aa53530b3f77), and after a tentative upgrade to that version, Jest can no longer resolve the module.

  ● Test suite failed to run

    Cannot find module 'is-what' from '~/js/utils'
    at resolveSync (node_modules/resolve/lib/sync.js:102:15)

The project itself is TypeScript, with babel-jest handling transpilation using (among others) @babel/preset-typescript and (crucially for Jest, and only in the Jest babel env) @babel/plugin-transform-modules-commonjs. (Let me know if you need full details.)

Setting the NODE_OPTIONS=--experimental-vm-modules envvar as recommended elsewhere has no effect on this (other than spamming the console with warnings about how ESM support is experimental).

The workaround is to explicitly tell Jest about the module's specifics, á la

  'transformIgnorePatterns': [
    'node_modules/(?!(is-what)/)',
  ],
  'moduleNameMapper': {
    'is-what': '<rootDir>/node_modules/is-what/dist/index.js',
  },

but that's not workable in the long run, especially as more modules turn ESM.

This is not isolated to the is-what module; Sindre's p-queue (ESM since 7.x) has the same problem.

To Reproduce

Attempt to import a pure-ESM module in a similarly configured repo. See https://github.com/akx/jest-esm-test (using p-queue as an example):

~/b/jest-esm-test (master) $ docker run -it -v (pwd):/app --workdir /app node:16 sh -c 'yarn && yarn jest'
yarn install v1.22.5
Done in 32.90s.
yarn run v1.22.5
$ /app/node_modules/.bin/jest
 FAIL  ./foo.test.js
  ● Test suite failed to run

    Cannot find module 'p-queue' from 'foo.test.js'

    > 1 | import pq from "p-queue";
        | ^
      2 |
      3 | it("does not crash", () => {
      4 |   const p = pq();

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:306:11)
      at Object.<anonymous> (foo.test.js:1:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        6.684 s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
~/b/jest-esm-test (master) $

Expected behavior

The module is resolved successfully, and in the best case automatically transpiled too in the absence of native ESM support in the Node runtime.

Link to repl or repo (highly encouraged)

https://github.com/akx/jest-esm-test

envinfo

  System:
    OS: macOS 10.15.7
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
  Binaries:
    Node: 16.0.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 7.10.0 - /usr/local/bin/npm
  npmPackages:
    jest: ^26.6.3 => 26.6.3
SimenB commented 3 years ago

p-queue does not use main, so Jest cannot resolve it (https://github.com/sindresorhus/p-queue/blob/76b81cd707a6cd31b41f25e5d7fa8abc7486c4bf/package.json#L9)

exports support is tracked in #9771

akx commented 3 years ago

@SimenB Thank you for the clarification. It's unfortunate that even with ESM modules there are multiple flavors of packaging like this...

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.