quasar: Bug in Vue v3.2.32/33 | Build Runtime Error | Cannot read properties of undefined (reading 'accessCache')

What happened?

As a developer that uses quasar using the Vite plugin When building a project that contains a quasar input component And previewing the build using npm run preview Then Vue throws an error Cannot read properties of undefined (reading 'accessCache')

You can find a codesandbox with the final build assets here: https://codesandbox.io/s/frosty-thunder-gxs0pt?file=/index.html

What did you expect to happen?

No error to happen in the final build

Reproduction URL

https://github.com/waldi/quasar-access-cache-bug

How to reproduce?

You can use the reproduction repo or create a new project from scratch:

  1. Create a new Vite project (Basically following all steps here: https://quasar.dev/start/vite-plugin)
npm init vite@latest quasar-access-cache-bug -- --template vue
cd quasar-access-cache-bug
npm install quasar @quasar/extras
npm install -D @quasar/vite-plugin sass@1.32.0
  1. Change files:
// main.js

import { createApp } from "vue";
import { Quasar } from "quasar";
import "@quasar/extras/material-icons/material-icons.css";
import "quasar/dist/quasar.css";

import App from "./App.vue";

const myApp = createApp(App);

myApp.use(Quasar, {
  plugins: {}, // import Quasar plugins and add here
});

myApp.mount("#app");
// vite.config.js

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { quasar, transformAssetUrls } from "@quasar/vite-plugin";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue({
      template: { transformAssetUrls },
    }),
    quasar(),
  ],
});

  1. Use q-input component:
// App.vue

<script setup>
import { ref } from "vue";
const text = ref("");
</script>

<template>
  <q-input v-model="text"> </q-input>
</template>

<style></style>
  1. Run npm run build && npm run preview
  2. Open app in browser
  3. Inspect developer console

Flavour

Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)

Areas

Quasar CLI Commands/Configuration (@quasar/cli | @quasar/app-webpack | @quasar/app-vite), Components (quasar), SPA Mode

Platforms/Browsers

No response

Quasar info output

No response

Relevant log output

index.103dbd67.js:1 
TypeError: Cannot read properties of undefined (reading 'accessCache')
    at Object.defineProperty (index.103dbd67.js:1:45265)
    at Function.defineProperty (<anonymous>)
    at $n (index.103dbd67.js:1:55812)
    at cc (index.103dbd67.js:1:94717)
    at vc (index.103dbd67.js:1:96942)
    at setup (index.103dbd67.js:1:114952)
    at tt (index.103dbd67.js:1:12393)
    at pa (index.103dbd67.js:1:46698)
    at ma (index.103dbd67.js:1:46483)
    at I (index.103dbd67.js:1:34874)

Additional context

This bug seems to be related to the Vue version. If you fix the vue version in the package.json to: "vue": "3.2.25" then everything works fine.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 15
  • Comments: 42 (13 by maintainers)

Commits related to this issue

Most upvoted comments

I ran git bisect on the vue repo and found this is the commit that broken ripple https://github.com/vuejs/core/commit/f44087e171282cb77f1e23d86516a527e4c5804b

The instance getting passed by invokeDirectiveHook is now a proxy object with only the component’s exposed field instead of everything in the original ComponentPublicInstance. This means the $q set on app.config.globalProperties is no longer available. This seems intentional as the docs say components using <script setup> are closed by default (https://vuejs.org/api/sfc-script-setup.html#defineexpose).

This means I have to explicitly run this code in my components that are using the v-ripple directive to expose the $q object

<script lang="ts" setup>
const $q = useQuasar()
defineExpose({
    $q,
})
</script>

May be related going from 3.2.31 to 3.2.32 also using Quasar with VUE CLI.

Ripple.js:65 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘config’) at updateModifiers (Ripple.js:65:31) at beforeMount (Ripple.js:112:1) at callWithErrorHandling (runtime-core.esm-bundler.js:155:1) at callWithAsyncErrorHandling (runtime-core.esm-bundler.js:164:1) at invokeDirectiveHook (runtime-core.esm-bundler.js:3753:1) at mountElement (runtime-core.esm-bundler.js:4651:1) at processElement (runtime-core.esm-bundler.js:4581:1) at patch (runtime-core.esm-bundler.js:4501:1) at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js:5052:1) at ReactiveEffect.run (reactivity.esm-bundler.js:185:1)

I experience the same issue with v-ripple directive

  • vue@3.2.33
  • quasar@2.6.6
Uncaught TypeError: instance.$q is undefined
    updateModifiers Ripple.js:65
const cfg = Object.assign({}, instance.$q.config.ripple, modifiers, value)

Latest changes in Vue: https://github.com/vuejs/core/commit/f641c4b2289dfdbbbea87538e36fa35f2a115ddc

@rstoenescu, please consider reopening it until the fix is confirmed, because those who use v-ripple get unhandled error that terminates the program

And its not vite related, same behaviour in webpack

I’m still getting the same Ripple.js error mentioned by others, it seems related. Works in vue 3.2.31, errors in 3.2.32 and 3.2.33

Debugging, it appears that instance.$q is undefined on some early calls, but then becomes defined after some ticks.

Patch version of Vue, 3.2.33 is released with a solution to this problem. Anyone stumbling upon it should run npm i vue to get the newest version.

https://github.com/vuejs/core/releases/tag/v3.2.33

With the v-ripple directive issue. From comments, there are 3 immediate work around:

  1. Downgrade to vue 3.2.31
  2. Keep vue ^3.2.33, that is now the recommended. Since latest update on vue, the developer need to explicit defineExpose({ $q }) on <script setup> on components using v-ripple.
  3. Stop using v-ripple on your components 😢.

But I like to propose to another temporary solution:

  • Add Optional chaining to Ripple.js:65 => const cfg = Object.assign({}, instance?.$q?.config?.ripple, modifiers, value).

I’m have created a PR proposing this change.

There is still the issue with vue ^3.2.33 not injecting $q and losing quasar.config, that need another workaround than defineExpose, but when this issue go fix, the optional chaining will be still valid.

Patch version of Vue, 3.2.33 is released with a solution to this problem. Anyone stumbling upon it should run npm i vue to get the newest version.

https://github.com/vuejs/core/releases/tag/v3.2.33

Worked for me. Thank you. I got the error using webpack.

May be related going from 3.2.31 to 3.2.32 also using Quasar with VUE CLI.

Ripple.js:65 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘config’) at updateModifiers (Ripple.js:65:31) at beforeMount (Ripple.js:112:1) at callWithErrorHandling (runtime-core.esm-bundler.js:155:1) at callWithAsyncErrorHandling (runtime-core.esm-bundler.js:164:1) at invokeDirectiveHook (runtime-core.esm-bundler.js:3753:1) at mountElement (runtime-core.esm-bundler.js:4651:1) at processElement (runtime-core.esm-bundler.js:4581:1) at patch (runtime-core.esm-bundler.js:4501:1) at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js:5052:1) at ReactiveEffect.run (reactivity.esm-bundler.js:185:1)

Also getting this even after upgrading to 3.2.33 (Qusar + Vite) So it is probably a bit different problem.

Ohh, sorry, ignore my comment from above in that case.

What you could to is downgrade Vue version manually until they release a fix with a npm i vue@3.2.31 or last one that worked for you.

I’ve started from the repro repo provided. From 3.2.33 onwards the issue no longer occurs. As @MilosPaunovic mentioned on 14th of april, this is the patch version that fixes the problem mentioned in this issue.

This issue can be closed.

The people having issues with v-ripple directive should create a repro repo with the exact steps to trigger the issue. Adding v-ripple on a div in this repo with Vue on version 3.2.33+ doesn’t have an error.

FWIW…

According to the ripple effects docs It seems that using v-ripple directive on any component that already has ripple baked causes the issue, but for me that wasn’t enough. Removing the v-ripple directive entirely from every component that used it actually fixed the issue for me.

Example: q-item uses the v-ripple directive without ripple being baked in, but the same issue occurs unless v-ripple is removed.

I removed the ripple directive and it works fine now.

vue 3.2.33 still have this error,when use script-setup

I’m still getting the same Ripple.js error mentioned by others, it seems related. Works in vue 3.2.31, errors in 3.2.32 and 3.2.33

Debugging, it appears that instance.$q is undefined on some early calls, but then becomes defined after some ticks.

Same, still erroring on 3.2.33 for Ripple.js

I have the same problem on prod, but on localhost quasar dev and quasar build works fine - no error

@MilosPaunovic thank you, downgrade to vue 3.2.31 solved the problem.

“vue”: “^3.2.35” still not solved.

I have the same problem! thank you!!

Same problem here, thanks for the fix instruction. Fixing the npm version of vue to 3.2.31 solved the problem!

Opened #13732 for the v-ripple issue.

@Liwoj globalProperties are discouraged, they were mostly a tool to migrate from vue 2 to vue 3 easily and it’s only meant for option api components, because in vue3 everything global was phased out and setup components should indeed be closed

So what quasar should do in this case is use provide inject, which is the recommended way to provide this kind of features with composables But it doesn’t seem to be possible to do within directives yet https://github.com/vuejs/core/issues/5002