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

fix: HMR not working correctly with vue-class-component components #1897

Merged
merged 1 commit into from Nov 4, 2021
Merged

fix: HMR not working correctly with vue-class-component components #1897

merged 1 commit into from Nov 4, 2021

Conversation

rstoenescu
Copy link
Contributor

vue-loader not registering "__hmrId" on the correct component property
when component is created with vue-class-component.

This leads to vue/compiler-sfc/runtime-core/src/render.ts mountComponent()
function to not call registerHMR() on the instance (because __hmrId is not
attached properly):

  if (__DEV__ && instance.type.__hmrId) {
    registerHMR(instance)
  }

Not registering for HMR means the createRecord() map will never get injected
any component instances, so when module.hot.accept() + api.rerender(id, render)
are called they will not apply any update due to finding no instances:

  module.hot.accept("./Index.vue?vue&type=template&id=4bc9d7de&ts=true", () => {
    console.log('re-render')
    api.rerender('4bc9d7de', render) // will never do anything; instances === []
  })

This commit fixes the exportComponent from src/exportHelper.ts by injecting the
properties (__file and later down the road __hmrId) to the correct component prop:

  import exportComponent from ".......-loader/dist/exportHelper.js"
  const __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__file',"src/pages/Index.vue"]])

  // ...
  /* hot reload */
  if (module.hot) {
    __exports__.__hmrId = "4bc9d7de" // we now have the correct __exports__

script reference should actually be script.__vccOpts for vue-class-component components,
which is what this commit fixes.

vue-loader not registering "__hmrId" on the correct component property
when component is created with vue-class-component.

This leads to vue/compiler-sfc/runtime-core/src/render.ts mountComponent()
function to not call registerHMR() on the instance (because __hmrId is not
attached properly):

  if (__DEV__ && instance.type.__hmrId) {
    registerHMR(instance)
  }

Not registering for HMR means the createRecord() map will never get injected
any component instances, so when module.hot.accept() + api.rerender(id, render)
are called they will not apply any update due to finding no instances:

  module.hot.accept("./Index.vue?vue&type=template&id=4bc9d7de&ts=true", () => {
    console.log('re-render')
    api.rerender('4bc9d7de', render) // will never do anything; instances === []
  })

This commit fixes the exportComponent from src/exportHelper.ts by injecting the
properties (__file and later down the road __hmrId) to the correct component prop:

  import exportComponent from ".......-loader/dist/exportHelper.js"
  const __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__file',"src/pages/Index.vue"]])

  // ...
  /* hot reload */
  if (module.hot) {
    __exports__.__hmrId = "4bc9d7de" // we now have the correct __exports__
Copy link
Member

@sodatea sodatea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@sodatea sodatea merged commit 76b1448 into vuejs:next Nov 4, 2021
@rstoenescu
Copy link
Contributor Author

Cheers! Thanks for making the release so quickly.

@rstoenescu rstoenescu deleted the next branch November 4, 2021 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants