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

vue2 tsx (class component) hmr exception #11008

Closed
7 tasks done
eleven-net-cn opened this issue Nov 21, 2022 · 8 comments · Fixed by #11059 or vitejs/vite-plugin-vue2#67
Closed
7 tasks done

vue2 tsx (class component) hmr exception #11008

eleven-net-cn opened this issue Nov 21, 2022 · 8 comments · Fixed by #11059 or vitejs/vite-plugin-vue2#67
Labels
feat: hmr p3-minor-bug An edge case that only affects very specific usage (priority)

Comments

@eleven-net-cn
Copy link

eleven-net-cn commented Nov 21, 2022

Describe the bug

vite@3 + vue2 + class component + tsx

When use lang="tsx" and class component, the vite hmr error.

See below about "Steps to reproduce" for details.

Reproduction

--

Steps to reproduce

dependencies

{
  "@vitejs/plugin-vue2": "^2.0.1",
  "@vitejs/plugin-vue2-jsx": "^1.0.3",
  "vite": "^3.2.3",
  "vue": "^2.7.14",
  "vue-class-component": "^7.2.6",
  "vue-property-decorator": "^9.1.2"
}

set lang="tsx"

<template>
  <el-form
    ref="form"
    :mode="value"
    size="mini"
    @submit.native.prevent
  >
    <el-form-item label="Test">
      <!-- e.g.: changed "v-model" to test1,  -->
      <el-input type="input" v-model="test" clearable />
    </el-form-item>
  </el-form>
</template>

<script lang="tsx">
import Vue from 'vue';
import { Component, Prop, Watch } from 'vue-property-decorator';
import type { TestProps } from '../types';

@Component({
  name: 'Test',
})
export default class Test extends Vue {
  @Prop()
  readonly value!: TestProps;

  // e.g.: changed "get test" to test1 
  get test() {
    return this.value.test;
  }
}
</script>

an error occurred when changed the get property, e.g.:

  1. changed v-model and get test to test1

  2. vite hmr

  3. we can find two requests in the network

    • .../form/index.vue?t=1668996911179

      It‘s right, the content is as follows

      image

    • .../form/index.vue?t=1668996911179&vue&type=script&lang.tsx

      Here is error, the content is still test

      image

Everything works fine when not using tsx (set lang="ts"), because only one hmr request (.../form/index.vue?t=1668996911179).

And, if I continue to add the set test1() {}, even if I add a new line, sometimes, the hmr request content is fine.

System Info

Chrome 107.0.5304.62 (arm64)

Used Package Manager

yarn

Logs

The error logs:

[Vue warn]: Property or method "test1" 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.

Validations

@sun0day
Copy link
Member

sun0day commented Nov 21, 2022

can you provide a mini-repro?

@github-actions
Copy link

Hello @eleven-net-cn. Please provide a minimal reproduction using a GitHub repository or StackBlitz. Issues marked with need reproduction will be closed if they have no activity within 3 days.

@eleven-net-cn
Copy link
Author

eleven-net-cn commented Nov 21, 2022

Hello @eleven-net-cn. Please provide a minimal reproduction using a GitHub repository or StackBlitz. Issues marked with need reproduction will be closed if they have no activity within 3 days.

Here it is:

https://github.com/eleven-net-cn/vite-vue2-tsx-hmr-error

@sun0day

@sun0day
Copy link
Member

sun0day commented Nov 24, 2022

I found this bug happens because of prevDescriptor incorrect cache in plugin-vue.

if (!isEqualBlock(descriptor.template, prevDescriptor.template)) {
// when a <script setup> component's template changes, it will need correct
// binding metadata. However, when reloading the template alone the binding
// metadata will not be available since the script part isn't loaded.
// in this case, reuse the compiled script from previous descriptor.
if (mainModule && !affectedModules.has(mainModule)) {
setResolvedScript(
descriptor,
getResolvedScript(prevDescriptor, false)!,
false
)
}
affectedModules.add(templateModule)
needRerender = true
}

Not sure what is the right way to fix it. Any suggestions?? @bluwy @sapphi-red. I can offer a PR.

@sapphi-red
Copy link
Member

The reproduction is using @vitejs/plugin-vue2 and @vitejs/plugin-vue2-jsx. These plugins are not maintained in this repo. It's https://github.com/vitejs/vite-plugin-vue2 and https://github.com/vitejs/vite-plugin-vue2-jsx.

@sun0day Do you mean this happens with plugin-vue + plugin-vue-jsx as well? If so I think it's better to create a PR directly because it's easier to discuss.

@sun0day
Copy link
Member

sun0day commented Nov 24, 2022

The reproduction is using @vitejs/plugin-vue2 and @vitejs/plugin-vue2-jsx. These plugins are not maintained in this repo. It's https://github.com/vitejs/vite-plugin-vue2 and https://github.com/vitejs/vite-plugin-vue2-jsx.

@sun0day Do you mean this happens with plugin-vue + plugin-vue-jsx as well? If so I think it's better to create a PR directly because it's easier to discuss.

The handleHotUpdate between plugin-vue2 and plugin-vue looks the same.

https://github.com/vitejs/vite-plugin-vue2/blob/eaa7886b2a0359af2589d4d31412c5136f60c3b9/src/handleHotUpdate.ts#L54-L68

Plus, I can ensure this happens in plugin-vue too.

See https://stackblitz.com/edit/vitejs-vite-r6uw9g?file=vite.config.js,index.html,src%2Fmain.ts,src%2Fhelloworld.vue,src%2FApp.vue,src%2Fassets%2Fbase.css,src%2Fassets%2Fmain.css,src%2Fassets%2Flogo.svg,package.json

I will give a try to offer a PR, let's discuss there. @sapphi-red

@patak-dev
Copy link
Member

@sun0day thanks for the fix! Has this issue been created also in the vite-plugin-vue2 repo?
Are you planing to send a PR there too?

@sun0day
Copy link
Member

sun0day commented Nov 25, 2022

@sun0day thanks for the fix! Has this issue been created also in the vite-plugin-vue2 repo? Are you planing to send a PR there too?

I'd love to, I will give a try

haoqunjiang pushed a commit to vitejs/vite-plugin-vue2 that referenced this issue Nov 29, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Dec 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feat: hmr p3-minor-bug An edge case that only affects very specific usage (priority)
Projects
None yet
4 participants