Skip to content

HMR is fetching multiple updated modules triggered by the same change in parallel and not in series #28

Closed
@rashfael

Description

@rashfael

Describe the bug

My original problem that lead me to this was:
When using vite, vue script setup, and pug as a template language, and updating both the script and template contents at once, the template compilation doesn't get the right context and produces wrong output, leading to errors in the browser.
This only seems to happen with pug (or other template preprocessors). When using plain html templates, the file is not split into multiple modules, even when changing both script and template at the same time.

I think this might be more a bug in vite than vue, because @vitejs/plugin-vue relies on the order in which modules are requested: the script being compiled first and when afterwards the template is compiled, accessing the cached script with the right bindingMetadata.

This doesn't seem to be the case however, the vite hmr client requests both modules in parallel, as seen in the devtools network tab here:
2022-11-22-18-04-53

If I modify the queueUpdate function I instead can get this behaviour, which fixes my problem:
2022-11-22-18-04-01

Looking closer, queueUpdate is called with the output from fetchUpdate, which seems to immediately fetch the module, and only queueing re-importing and not the module request itself.
For the pug template to get the proper bindingMetadata however, compilation of the script module needs to finish before the template is requested.

Here is my hacky fix, but I'm not sure if this is the correct thing to fix or if maybe changing how @vitejs/plugin-vue handles multiple modules is a better approach.

Reproduction

https://github.com/rashfael/vite-hmr-multiple-modules

Steps to reproduce

Vite HMR repro

  1. npm ci
  2. npm run dev
  3. open localhost:5173
  4. change both script and template in App.vue and save at the same time
  5. Get Property "foo" was accessed during render but is not defined on instance. in the browser console

System Info

System:
    OS: Linux 6.0 Arch Linux
    CPU: (16) x64 AMD Ryzen 7 PRO 6850H with Radeon Graphics
    Memory: 12.41 GB / 30.63 GB
    Container: Yes
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 19.0.1 - /usr/bin/node
    Yarn: 1.22.19 - /usr/bin/yarn
    npm: 8.19.2 - /usr/bin/npm
  Browsers:
    Chromium: 107.0.5304.110
    Firefox: 106.0.5
  npmPackages:
    @vitejs/plugin-vue: ^3.2.0 => 3.2.0
    vite: ^3.2.4 => 3.2.4

Used Package Manager

npm

Logs

Browser logs
[vite] connected.
[Vue warn]: Property "foo" was accessed during render but is not defined on instance.   
[vite] hot updated: /src/App.vue
[Vue warn]: Property "foo" was accessed during render but is not defined on instance. 
[vite] hot updated: /src/App.vue?vue&type=template&lang.js

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions