vitejs / vite-plugin-vue

Vite Vue Plugins
MIT License
501 stars 154 forks source link

How to differentiate between HMR change on template vs script #103

Open alvarosabu opened 1 year ago

alvarosabu commented 1 year ago

Related plugins

Description

Hi there,

For the TresJS library, we need to dispose of 3D scene objects on HMR, the problem is that right now we have no way of differentiating whether the change came from the <template> or from <script>.

  if (import.meta.hot) {
    import.meta.hot.on('vite:beforeUpdate', context => {
      console.log('vite:beforeUpdate', context)
      scene.value.remove(instance)
    })

    import.meta.hot.on('vite:afterUpdate', context => {
      console.log('vite:afterUpdate', context)
      instance = createInstance(threeObj, attrs, slots)
      processProps(attrs, instance)

      if (instance.isObject3D) {
        scene?.value.add(instance)
      }
    })
  }

The problem is that this code works well when the change comes from the template, but if the change comes from the script tag the creation of 3D instances is loaded again, causing duplicate objects on the scene

I checked the value coming from both vite:beforeUpdate and vite:afterUpdate but I don't see any info that could help me differentiate between both

{
    "type": "update",
    "updates": [
        {
            "type": "js-update",
            "timestamp": 1676285908707,
            "path": "/src/components/TheEvents.vue",
            "explicitImportRequired": false,
            "acceptedPath": "/src/components/TheEvents.vue"
        }
    ]
}

Suggested solution

Maybe return a property with the origin of the change? Like so

{
    "type": "update",
    "updates": [
        {
            "type": "js-update",
            "timestamp": 1676285908707,
            "path": "/src/components/TheEvents.vue",
             "block": "template"
            "explicitImportRequired": false,
            "acceptedPath": "/src/components/TheEvents.vue"
        }
    ]
}

Alternative

No response

Additional context

No response

Validations

alvarosabu commented 1 year ago

Possible Solution https://github.com/vitejs/vite/issues/12097

sapphi-red commented 8 months ago

I guess you can differentiate the update by checking _rerender_only variable. https://github.com/vitejs/vite-plugin-vue/blob/2050ad3dc568b4d051d19611aad34693e9a917ec/packages/plugin-vue/src/main.ts#L146-L164

edison1105 commented 2 months ago

@alvarosabu Does the above solution solve your problem?

alvarosabu commented 1 month ago

Hi there @edison1105 the truth is that I haven't yet tried it out the solution @sapphi-red proposed. I will give it a try. Thanks