vueuse/vue-demi

Reactivity loss when using with @vue/compat

bgoscinski opened this issue · 1 comments

Reproduction

https://github.com/bgoscinski/repro-vue-compat-reactivity

Steps to reproduce the bug

  1. Run npm install
  2. Run npm test. Test fails
  3. Remove 'vue': '@vue/compat' alias from ./vite.config.js
  4. Run npm test again. Test passes 🤯

Expected behavior

Reactivity is preserved when using vue-demi with @vue/compat

Actual behavior

No/broken reactivity

Additional information

I think that vue-demi doesn't use the reactivity primitives from @vue/compat so we end up with both of these loaded at the same time:

  • node_modules/@vue/compat/dist/vue.cjs.js
  • node_modules/@vue/reactivity/dist/reactivity.cjs.js

Because of that the component's render effect is not tracking all reactive values properly.

I'm coming from vuejs/pinia#2565 but it's still not clear for me how to properly configure aliases and I think it would be beneficial for the whole ecosystem to have this documented somewhere.

I figured out that to make vite apply the 'vue': '@vue/compat' alias inside vue-demi source it needs to be inlined like so:

 // vitest.config.js
 export default mergeConfig(
   viteConfig,
   defineConfig({
     test: {
       environment: 'jsdom',
       root: fileURLToPath(new URL('./', import.meta.url)),
+      server: {
+        deps: {
+          inline: ['vue-demi'],
+        },
+      },
     },
   }),
 );

However once I did that I got a different error:

 FAIL  repro.spec.js > maintains reactivity
TypeError: ref is not a function
 ❯ repro.spec.js:8:15
      6| test('maintains reactivity', async () => {
      7|  const vRef = vueRef(0);
      8|  const dRef = demiRef(0);
       |               ^
      9| 
     10|  const Comp = defineComponent({

When I stop there in debugger I can see that the vue-demi import is not quite like it should:

image

I'd expect __vite_ssr_import_3__.ref to evaluate to the same value as __vite_ssr_import_2__.ref. At this point I'm out of ideas and would appreciate any pointers