Subscribe on changes!

Error when unmounting after ssr if async component not loaded yet

avatar
May 17th 2021

Version

3.1.0-beta.3

Reproduction link

https://github.com/danelowe/vite-ssr-lazy-component

Steps to reproduce

  • Clone reproducer.
  • Run npm run dev
  • Load the index page in browser directly from ssr (i,e, refresh on /)
  • Navigate to about page

What is expected?

Displays the about page with no error

What is actually happening?

Error:

Uncaught (in promise) TypeError: instance is null
    unmountComponent runtime-core.esm-bundler.js:4818
    unmount runtime-core.esm-bundler.js:4736
    unmountChildren runtime-core.esm-bundler.js:4864
    unmount runtime-core.esm-bundler.js:4754
    unmountComponent runtime-core.esm-bundler.js:4835
    unmount runtime-core.esm-bundler.js:4736
    resolve runtime-core.esm-bundler.js:1328
    registerDep runtime-core.esm-bundler.js:1452
    promise callback*registerDep runtime-core.esm-bundler.js:1414
    mountComponent runtime-core.esm-bundler.js:4213
    processComponent runtime-core.esm-bundler.js:4182

In. 3.1.0-beta.3

Uncaught (in promise) TypeError: vnode is null
    unmount runtime-core.esm-bundler.js:5619
    unmountComponent runtime-core.esm-bundler.js:5733
    unmount runtime-core.esm-bundler.js:5634
    unmountChildren runtime-core.esm-bundler.js:5762
    unmount runtime-core.esm-bundler.js:5652
    unmountComponent runtime-core.esm-bundler.js:5733
    unmount runtime-core.esm-bundler.js:5634
    resolve runtime-core.esm-bundler.js:1672
    registerDep runtime-core.esm-bundler.js:1796

I took the example at https://github.com/vitejs/vite/tree/main/packages/playground/ssr-vue, removed the dep-import-type dependency, added vite as a dependency. then modified the import of the Foo component to chain it's loading to an unresolved promise when rendering client-side.

The intention is to lazy-load/hydrate some components client-side, so any tips on how to achieve this would be appreciated.

In any case, I think this is a significant bug as it would cause errors when navigating before components are able to be loaded.

avatar
May 18th 2021

This is a minimized repro:

const AsyncComp = defineAsyncComponent(() => new Promise((r) => {}))

const CompA = defineComponent({
  render: () => h(AsyncComp)
})

const CompB = defineComponent({
  render: () => 'foo'
})

createSSRApp({
  setup() {
    const comp = shallowRef(CompA)

    return () => {
      return [
        h(comp.value),
        h('button', { onClick() { comp.value = CompB } }, 'click me')
      ]
    }
  }
}).mount('#app')

Use the following html as server-side rendering content

<div id="app"><!--[--><div></div><button>click</button><!--]--></div>