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

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

Closed
7 tasks done
rashfael opened this issue Nov 22, 2022 · 1 comment · Fixed by #106
Closed
7 tasks done

Comments

@rashfael
Copy link
Contributor

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

@rashfael
Copy link
Contributor Author

Another, perhaps better solution is to fix this in @vitejs/plugin-vue by compiling the script when transforming the template, if it's not in the cache yet. The request for the script module that comes too late can then grab the compiled script from cache.
Something like this?
rashfael/vite-hmr-queue-updates@7d05692

@patak-dev patak-dev transferred this issue from vitejs/vite Dec 3, 2022
rashfael added a commit to rashfael/vite-plugin-vue that referenced this issue Feb 14, 2023
haoqunjiang pushed a commit that referenced this issue Jul 15, 2023
… same time with a template preprocessor (#106)

Fixes #28 
Fixes #76
@github-actions github-actions bot locked and limited conversation to collaborators Jul 30, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
1 participant