react-hook icon indicating copy to clipboard operation
react-hook copied to clipboard

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

Open alex-l-miro opened this issue 2 years ago • 9 comments

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

alex-l-miro avatar Apr 12 '23 15:04 alex-l-miro

@jaredLunde Friendly ping! ☝️

guidobouman avatar Apr 14 '23 12:04 guidobouman

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

SebiBasti avatar Apr 16 '23 15:04 SebiBasti

Yep looking into it

jaredLunde avatar Apr 16 '23 16:04 jaredLunde

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

yoo2001818 avatar Apr 21 '23 03:04 yoo2001818

Any progress on this?

edward-simpson avatar May 30 '23 22:05 edward-simpson

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

jaredLunde avatar May 31 '23 02:05 jaredLunde

@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.

karlnorling avatar Aug 22 '23 13:08 karlnorling

Workaround

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

YauheniKhadanionak avatar Dec 07 '23 12:12 YauheniKhadanionak

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;
    },
  });

eric-helier avatar Mar 21 '24 10:03 eric-helier