vitest: Can not run tests when using preact compat alias

Describe the bug

When package tries to import react by alias, it picks CJS version of preact specific module, which leads to following error:

 FAIL  src/app.test.tsx > should render app
TypeError: Cannot read properties of undefined (reading '__H')
 ❯ l node_modules/preact/hooks/dist/hooks.js:1:201
 ❯ d node_modules/preact/hooks/dist/hooks.js:1:600
 ❯ Object.exports.useRef node_modules/preact/hooks/dist/hooks.js:1:2323
 ❯ d.BrowserRouter [as constructor] node_modules/react-router-dom/umd/react-router-dom.development.js:80:28
 ❯ d.O [as render] ../../../../../../../../../C:/Users/wight/Documents/preact-vitest-repro/node_modules/preact/dist/preact.mjs:1:8158
 ❯ j ../../../../../../../../../C:/Users/wight/Documents/preact-vitest-repro/node_modules/preact/dist/preact.mjs:1:5870
 ❯ w ../../../../../../../../../C:/Users/wight/Documents/preact-vitest-repro/node_modules/preact/dist/preact.mjs:1:2137
 ❯ j ../../../../../../../../../C:/Users/wight/Documents/preact-vitest-repro/node_modules/preact/dist/preact.mjs:1:6138
 ❯ P ../../../../../../../../../C:/Users/wight/Documents/preact-vitest-repro/node_modules/preact/dist/preact.mjs:1:8272
 ❯ ../../../../../../../../../C:/Users/wight/Documents/preact-vitest-repro/node_modules/@testing-library/preact/dist/esm/pure.mjs:52:7

Reproduction

https://github.com/wight554/preact-vitest-repro/

System Info

System:
    OS: Windows 10 10.0.22621
    CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
    Memory: 16.89 GB / 31.93 GB
  Binaries:
    Node: 16.14.0 - c:\program files\nodejs\node.EXE
    Yarn: 1.22.4 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 8.3.1 - c:\program files\nodejs\npm.CMD
  Browsers:
    Chrome: 103.0.5060.114
    Edge: Spartan (44.22621.290.0), Chromium (103.0.1264.49)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    vite: ^3.0.0 => 3.0.0
    vitest: ^0.18.0 => 0.18.0

Used Package Manager

yarn

Validations

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 4
  • Comments: 30 (11 by maintainers)

Most upvoted comments

Upd. cleanest solution I was able to implement:

import { createRequire } from 'module';

const require = createRequire(import.meta.url);

    alias: [
      {
        find: 'preact/hooks',
        replacement: require.resolve('preact/hooks'),
      },
      {
        find: '@testing-library/preact',
        replacement: require.resolve('@testing-library/preact'),
      },
    ],

Upd2. Can be splitted to simple:

const generateCjsAlias = (cjsPackages: Array<string>) => {
  const require = createRequire(import.meta.url);

  return cjsPackages.map((p) => ({
    find: p,
    replacement: require.resolve(p),
  }));
};

    alias: [...generateCjsAlias(['preact/hooks', '@testing-library/preact'])],

I don’t mind having this in codebase or as separate plugin, but still would be nicer to see smth like this in vitest itself, either way issue can be closed since there’s acceptable fix

I guess vite can’t transpile this?

Vitest doesn’t support aliasing require calls, yes. There is an open issue: https://github.com/vitest-dev/vitest/issues/1910