Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using Preact and Svelte Vite plugins together, Preact tests suddenly fail #737

Closed
6 tasks done
molily opened this issue Feb 11, 2022 · 8 comments
Closed
6 tasks done
Labels

Comments

@molily
Copy link
Contributor

molily commented Feb 11, 2022

Describe the bug

[This is a follow-up to #367. The test case I had provided now works fine, thanks!]

In my project, I’m using Preact and Svelte together. Some components are Preact, some Svelte.

Both work fine together in Vite using @preact/preset-vite and @sveltejs/vite-plugin-svelte.

They also work separately in Vitest. But when I use both, the Preact test suddenly fails – just by adding Svelte’s Vite plugin.

The Preact component in question calls useState. This is where the test fails.

This might be an issue in @preact/preset-vite or @sveltejs/vite-plugin-svelte. But I don’t know where to start to pin this down. Are the plugins interfering with each other? If so, it produces an error in Vitest, not in pure Vite.

If you have any clue what’s going wrong here, I’m happy to forward it to the respective maintainers.

Thanks a lot!

Reproduction

Minimal example: https://github.com/molily/vitest-test/tree/preact-and-svelte

vite.config.js:

    plugins: [
      preact(),
      svelte({
        // Disable HMR in test env
        hot: !process.env.VITEST,
      }),
    ],
$ npx vitest

 WATCH  /Users/molily/projects/vitest-test

 √ src/Counter.svelte.test.js (1)
 ❯ src/Counter.test.js (1)
   × renders the count

⎯⎯⎯ Failed Tests 1 ⎯⎯⎯

 FAIL  src/Counter.test.js > renders the count
TypeError: Cannot read properties of undefined (reading '__H')
 ❯ m file:/Users/molily/projects/vitest-test/node_modules/.pnpm/preact@10.6.4/node_modules/preact/hooks/dist/hooks.mjs:1:151
 ❯ p file:/Users/molily/projects/vitest-test/node_modules/.pnpm/preact@10.6.4/node_modules/preact/hooks/dist/hooks.mjs:1:280
 ❯ Module.l file:/Users/molily/projects/vitest-test/node_modules/.pnpm/preact@10.6.4/node_modules/preact/hooks/dist/hooks.mjs:1:249
 ❯ d.Counter [as constructor] src/Counter.jsx:5:28
      3|
      4| export const Counter = () => {
      5|   const [count, setCount] = useState(0)
       |                            ^
      6|
      7|   return (

If I remove svelte(…) from vite.config.js, the Preact component test is green.

System Info

System:
    OS: macOS 12.2.1
  Binaries:
    Node: 16.13.2
  npmPackages:
    vite: ^2.7.9 => 2.7.9
    vitest: ^0.3.2 => 0.3.2

Used Package Manager

pnpm

Validations

@sheremet-va
Copy link
Member

We have the same error here: #747

@sheremet-va
Copy link
Member

This is probably cased by this: testing-library/preact-testing-library#50

Althought it's weird that it's working if you don't use Svelte 🤔

@sheremet-va
Copy link
Member

So, I identified the problem. Svelte plugin adds module to resolution fields (resolve.mainFields), so now Vite also crawls module field. And preact/hooks is pointing to the wrong ESM file in their package.json.

There a two questions tho:

  • Why preact has package.json there?
  • Why Vite prioritizes closes package json instead of top level exports?

To fix this, you can add your alias, pointing to the correct file:

    resolve: {
      alias: [
        {
          find: /^preact\/hooks$/,
          replacement: resolve(
            dirname,
            'node_modules/.pnpm/preact@10.7.3/node_modules/preact/hooks/dist/hooks.mjs'
          ),
        },
      ],
    },

@rschristian
Copy link

That file is correct. hooks.module.js is an ESM entry.

Echoing what I said on the Preact issue, but Vitest enforcing Node's extension semantics (.mjs/.cjs) on "module" would be incorrect behavior, as a) Node doesn't read the entry, so it doesn't need to abide by Node's semantics and b) it is far, far older than Node even having those semantics. Any package that is significantly old enough will run into issues.

Not to mention that React Native/Expo (just an example) still does not support the .mjs extension, but does read from "module". Any package that wishes to support Expo AND ship ESM will do so via the .js extension. See this recent issue over in Immer when they tried to change this: immerjs/immer#937

@sheremet-va
Copy link
Member

Fixed in preactjs/preact#3564

@molily
Copy link
Contributor Author

molily commented Jun 17, 2022

Thanks everyone for investigating and fixing this!

@molily
Copy link
Contributor Author

molily commented Jan 24, 2023

Hi, I'm getting the same error again in my example case (dependencies updated to latest versions) with Node 16 and 18:
https://github.com/molily/vitest-test/tree/preact-and-svelte
Preact tests pass until I add @sveltejs/vite-plugin-svelte to the game.

 FAIL  src/Counter.test.jsx > renders the count
TypeError: Cannot read properties of undefined (reading '__H')
 ❯ d node_modules/.pnpm/preact@10.11.3/node_modules/preact/hooks/dist/hooks.module.js:2:321
 ❯ y node_modules/.pnpm/preact@10.11.3/node_modules/preact/hooks/dist/hooks.module.js:2:455
 ❯ Module.useState node_modules/.pnpm/preact@10.11.3/node_modules/preact/hooks/dist/hooks.module.js:2:424
 ❯ d.constructor src/Counter.jsx:5:29
 ❯ d.render node_modules/.pnpm/preact@10.11.3/node_modules/preact/src/diff/index.js:554:14
 ❯ diff node_modules/.pnpm/preact@10.11.3/node_modules/preact/src/diff/index.js:203:14
 ❯ diffChildren node_modules/.pnpm/preact@10.11.3/node_modules/preact/src/diff/children.js:137:3
 ❯ diff node_modules/.pnpm/preact@10.11.3/node_modules/preact/src/diff/index.js:225:4
 ❯ P node_modules/.pnpm/preact@10.11.3/node_modules/preact/src/render.js:39:2
 ❯ node_modules/.pnpm/@testing-library+preact@3.2.3_preact@10.11.3/node_modules/@testing-library/preact/dist/esm/pure.mjs:48:7

Is this still an import issue? Now hooks.module.js is used, is this correct? If Preact is doing all what it can, can@sveltejs/vite-plugin-svelte probably do something to not break other libraries? 🧐 I'm trying to figure out which library involved can solve this issue for good.

Thanks for looking into this!

@sheremet-va
Copy link
Member

Is this still an import issue? Now hooks.module.js is used, is this correct? If Preact is doing all what it can, can@sveltejs/vite-plugin-svelte probably do something to not break other libraries? 🧐 I'm trying to figure out which library involved can solve this issue for good.

Yes, svelte plugin adds "module" field to resolve.mainFields: https://github.com/sveltejs/vite-plugin-svelte/blob/e9129c6d5183ac0ee0f746905808e0b3232d4d3f/packages/vite-plugin-svelte/src/utils/constants.ts

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants