Skip to content

HMR Problems in Vite6 and Vue2: Property or method "_isBuffer" is not defined #2197

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

Closed
youthug opened this issue Dec 20, 2024 · 1 comment
Closed

Comments

@youthug
Copy link

youthug commented Dec 20, 2024

Vue devtools version

6.6.4

Link to minimal reproduction

https://github.com/youthug/vite-vuex-state-repro

Steps to reproduce & screenshots

Since migrating to Vite in our Vue 2 project, we've encountered an HMR issue with Vuex:

When the store modules have circular dependencies, the store's state is reset after an HMR. I've submitted an issue here: vitejs/vite-plugin-vue2#103, but there haven't been any responses so far. Therefore, I'm attempting to find some workarounds myself.

Inspired by vitejs/vite#3301 (comment), I've created a Vite plugin to restore the store's state after an HMR:

// vite.config.ts
const vuexStateHmr = (): PluginOption => {
  const importingRegEx = /(import.*store.*)/

  const updateState = `
  import.meta.hot.on('vite:beforeUpdate', (payload) => {
    if (payload.updates.some((u) => u.isWithinCircularImport)) {
      payload._state = { ...store.state }
    }
  });
  import.meta.hot.on('vite:afterUpdate', (payload) => {
    if (payload._state) {
      store.replaceState(payload._state)
    }
  });
  `

  return {
    name: 'vuexStateHmr',
    transform(code: string) {
      if (!code.match(importingRegEx)) return;
      return {
        code: code.replace(importingRegEx, `$1\n${updateState}`),
        map: null,
      }
    }
  }
}

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vuexStateHmr(),
  ],
  // ...
})

Now the state can be restored automatically after HMR, but got new errors in the console:

hook-exec.js:1 [Vue warn]: Property or method "_isBuffer" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

found in

---> <ElMenuItem> at packages/menu/src/menu-item.vue
       <ElMenuItemGroup> at packages/menu/src/menu-item-group.vue
         <ElScrollbar>
           <ElMenu> at packages/menu/src/menu.vue
             <ElRow>
...

How do I fix this error properly? Thanks!

What is expected?

No errors during HMR.

What is actually happening?

Errors occurred.

System Info

System:
    OS: macOS 15.0.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 62.84 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.19.0 - ~/.nvm/versions/node/v18.19.0/bin/node
    Yarn: 1.22.21 - ~/.nvm/versions/node/v18.19.0/bin/yarn
    npm: 10.2.3 - ~/.nvm/versions/node/v18.19.0/bin/npm
    pnpm: 9.4.0 - ~/.nvm/versions/node/v18.19.0/bin/pnpm
  Browsers:
    Chrome: 131.0.6778.205
    Safari: 18.0.1
  npmPackages:
    vue: ^2.7.16 => 2.7.16

Any additional comments?

image

I have both versions of devtools but only enabled the legacy one.

@youthug
Copy link
Author

youthug commented Dec 23, 2024

I found a simpler way to fix this. Add the following code in src/store/index.js:

if (import.meta.hot) { // for tree-shaking
    import.meta.hot.accept(
        [
            './modules/user.js',
        ],
        () => {
            // Not handling hot updates; the purpose is to resolve the issue where the state is reset after a hot update due to circular dependencies
            window.location.reload()
        },
    )
}

@youthug youthug closed this as completed Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant