Skip to content

vue-loader/next registerHMR(instance)的bug #1626

@doter1995

Description

@doter1995

Version

16.0.0-alpha.1

Reproduction link

https://github.com/doter1995/vue3-test/tree/vue-loader_bug_demo

Steps to reproduce

在webpack中devServer.hot没有开启时。运行webpack-dev-server。
由于vue-loader对vue转换后,生成下面代码。

/* hot reload */
if (module.hot) {
  const api = __VUE_HMR_RUNTIME__
  module.hot.accept()
  if (!api.createRecord('7ba5bd90', script)) {
    api.reload('7ba5bd90', script)
  }
  
  module.hot.accept("./App.vue?vue&type=template&id=7ba5bd90&scoped=true", () => {
    api.rerender('7ba5bd90', render)
  })
}

从而不会createRecord
在页面加载时报错:Uncaught TypeError: Cannot read property 'instances' of undefined

定位源码:

function mountComponent(initialVNode, container, anchor, parentComponent, parentSuspense, isSVG) {
        const instance = (initialVNode.component = defineComponentInstance(initialVNode, parentComponent));
        //这里并没有判断webpack是否配置hot,从而直接调用registerHMR
        if (__HMR__ && instance.type.__hmrId != null) {
            registerHMR(instance);
        }

同时map.get(instance.type.__hmrId)由于没有调用过createRecord从而返回null。如下代码机会报错:

function registerHMR(instance) {
    map.get(instance.type.__hmrId).instances.add(instance);
}
function unregisterHMR(instance) {
    map.get(instance.type.__hmrId).instances.delete(instance);
}

此处

What is expected?

export function registerHMR(instance: ComponentInternalInstance) {
  const record = map.get(instance.type.__hmrId!)
  if (record && record.instances){
    record.instances.add(instance)
  }
}

export function unregisterHMR(instance: ComponentInternalInstance) {
  const record = map.get(instance.type.__hmrId!)
  if (record && record.instances){
    record.instances.delete(instance)
  }
}

What is actually happening?

/packages/runtime-core/src/hmr.ts

export function registerHMR(instance: ComponentInternalInstance) {
  map.get(instance.type.__hmrId!)!.instances.add(instance)
}

export function unregisterHMR(instance: ComponentInternalInstance) {
  map.get(instance.type.__hmrId!)!.instances.delete(instance)
}

不确定是否应该这样修复

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions