jaredLunde / react-hook

↩ Strongly typed, concurrent mode-safe React hooks
https://npmjs.com/org/react-hook
MIT License
1.42k stars 95 forks source link

jest-environment-jsdom 28+ tries to use browser exports instead of default exports #300

Open alex-l-miro opened 1 year ago

alex-l-miro commented 1 year ago

Describe the bug jest-environment-jsdom v28+ tries to use browser exports instead of default exports which generates the following error when Jest testEnvironment: 'jsdom':

Jest encountered an unexpected token

      Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

To Reproduce Steps to reproduce the behavior:

  1. git clone https://github.com/alex-l-miro/react-hook-bug.git
  2. yarn
  3. yarn test

Expected behavior Jest should not fail when testEnvironment is jsdom

guidobouman commented 1 year ago

@jaredLunde Friendly ping! ☝️

SebiBasti commented 1 year ago

I'm having the same problem with jest-environment-jsdom 29.5.0:

({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import React from 'react';
                                                                                  ^^^^^^

SyntaxError: Cannot use import statement outside a module
jaredLunde commented 1 year ago

Yep looking into it

yoo2001818 commented 1 year ago

Hello! While I think it's certainly better to provide both CommonJS and ESM modules in browsers, however this problem is only occurring in jest environments because jest doesn't support ESM modules by default. In other words, many other environments like webpack, tsc, etc already supports ESM, and would work quite well without any problem.

I've encountered the same problem and looked into it. Can you check the following comment and if it works for you? https://github.com/facebook/jest/issues/13739#issuecomment-1517190965

edward-simpson commented 1 year ago

Any progress on this?

jaredLunde commented 1 year ago

yeah ngl if it doesn't affect me personally it's harder to make time for 😏 would like to get to it but haven't had time

karlnorling commented 1 year ago

@jaredLunde With jest 28 now supporting exports. Node and jest might interpret your resize-observer as "commonJS" module.

Looking at https://nodejs.org/api/packages.html#type - not adding type: "module" it defaults to commonJS. And therefore maybe the "default" in exports doesn't get used and defaults to be using "import" because the package is deemed to be commonJS?

Just speculating of course, need to validate my thoughts.

YauheniKhadanionak commented 9 months ago

Workaround

// jest.config.js
module.exports = {
  ...
  moduleNameMapper: { '@react-hook/(.*)': '<rootDir>/node_modules/@react-hook/$1/dist/main' }
}
eric-helier commented 6 months ago

We have been able to workaround this issue also with some jest configuration using the resolver option. See https://jestjs.io/docs/configuration#resolver-string

return options.defaultResolver(path, {
    ...options,
    // Use packageFilter to process parsed `package.json` before
    // the resolution (see https://www.npmjs.com/package/resolve#resolveid-opts-cb)
    packageFilter: (pkg) => {
      // jest-environment-jsdom 28+ tries to use browser exports instead of default exports,
      // but @react-hook/resize-observer only offers an ESM browser export and not a CommonJS one. Jest does not yet
      // support ESM modules natively, so this causes a Jest error related to trying to parse
      // "export" syntax.
      //
      // This workaround prevents Jest from considering @react-hook/resize-observer module-based exports at all;
      // it falls back to CommonJS+node "main" property.
      if (typeof pkg.name === "string" && pkg.name.startsWith("@react-hook/")) {
        delete pkg["exports"];
        delete pkg["module"];
      }
      return pkg;
    },
  });