Skip to content

HMR throws error when SFC contains style tag injected by plugin #301

@auvred

Description

@auvred

Related plugins

Describe the bug

In the provided reproduction, the SFC should contain two <style> tags: the first one is written explicitly in the file, the second one is appended to the end of the file in transform/handleHotUpdate hooks

The error appears when handleHotUpdate is called, the cached file descriptor is invalidated:

if (file.endsWith('.vue')) {
// invalidate the descriptor cache so that the next transform will
// re-analyze the file and pick up the changes.
invalidateDescriptor(file)
A detailed explanation of what happens next is written here:
// https://github.com/vuejs/vitepress/issues/3129
// For non-vue files, e.g. .md files in VitePress, invalidating the
// descriptor will cause the main `load()` hook to attempt to read and
// parse a descriptor from a non-vue source file, leading to errors.
// To fix that we need to provide the descriptor we parsed here in the
// main cache. This assumes no other plugin is applying pre-transform to
// the file type - not impossible, but should be extremely unlikely.
cache.set(file, descriptor)

So basically, after invalidation, the load() hook reads file source without any plugin transformations. And if the file contains two style tags, as in the reproduction (one of them in injected in transform), then getDescriptor caches the file without second style.


It's very similar to vuejs/vitepress#3129, however in that case it was about .md files and a26a854 fixed it perfectly


The unocss uses this trick to inject resolved classes to the <style scoped>
https://github.com/unocss/unocss/blob/6aa1578976c902b315dd500a533a088456de67d8/packages/vite/src/modes/vue-scoped.ts#L28-L41
Related: unocss/unocss#3358

Reproduction

https://stackblitz.com/edit/vitejs-vite-n7dupt?file=src%2FApp.vue

Steps to reproduce

  1. Open reproduction
  2. Wait for dev server to start
  3. Change something in src/App.vue

System Info

System:
    OS: Linux 6.2 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish)
    CPU: (16) x64 AMD Ryzen 7 5800H with Radeon Graphics
    Memory: 21.62 GB / 31.19 GB
    Container: Yes
    Shell: 5.8.1 - /usr/bin/zsh
  Binaries:
    Node: 18.18.2 - ~/.asdf/installs/nodejs/18.18.2/bin/node
    npm: 9.8.1 - ~/.asdf/plugins/nodejs/shims/npm
    pnpm: 8.10.5 - ~/.asdf/installs/nodejs/18.18.2/bin/pnpm
    Watchman: 20231008.002904.0 - /usr/local/bin/watchman
  npmPackages:
    @vitejs/plugin-vue: 4.5.0 => 4.5.0
    vite: 5.0.2 => 5.0.2

Used Package Manager

npm

Logs

Click to expand!
2:29:22 PM [vite] hmr update /src/App.vue?vue&type=style&index=0&scoped=7a7a37b1&lang.css, /src/App.vue?vue&type=style&index=1&scoped=7a7a37b1&lang.css
2:29:22 PM [vite] Internal server error: Cannot read properties of undefined (reading 'scoped')
  Plugin: vite:vue
  File: /home/projects/vitejs-vite-n7dupt/src/App.vue?vue&type=style&index=1&scoped=7a7a37b1&lang.css
      at transformStyle (file:///home/projects/vitejs-vite-n7dupt/node_modules/@vitejs/plugin-vue/dist/index.mjs:2681:19)
      at TransformContext.transform (file:///home/projects/vitejs-vite-n7dupt/node_modules/@vitejs/plugin-vue/dist/index.mjs:2871:18)
      at Object.transform (file:///home/projects/vitejs-vite-n7dupt/node_modules/vite/dist/node/chunks/dep-ErEj4WmL.js:62057:62)
      at async loadAndTransform (file:///home/projects/vitejs-vite-n7dupt/node_modules/vite/dist/node/chunks/dep-ErEj4WmL.js:47839:29)
      at async viteTransformMiddleware (file:///home/projects/vitejs-vite-n7dupt/node_modules/vite/dist/node/chunks/dep-ErEj4WmL.js:57435:32)

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    p2-nice-to-have 🍰Not breaking anything but nice to have (priority)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions