Subscribe on changes!

[Vite + Renderer] Component proxy is undefined (hydration error with Async components)

avatar
Nov 17th 2020

When hydrating an SSR application that makes use of async components, an error is thrown:

Screen Shot 2020-11-17 at 1 45 44 PM

The line throwing the error is here: https://github.com/vuejs/vue-next/blob/3a6b1207fa39cb35eed5bae0b5fdcdb465926bca/packages/runtime-core/src/renderer.ts#L314

Version

3.0.2

Reproduction link

https://github.com/fiction-com/vite-vue-poc

Steps to reproduce

Create SSR application and attempt hydration with an app that uses Async components.

What is expected?

Hydration occurs smoothy.

What is actually happening?

Error is thrown "Uncaught (in promise) TypeError: Cannot read property 'proxy' of null"

avatar
Nov 17th 2020

Note in the example that router.ready() is awaited at which point all async components should be resolved.

avatar
Nov 17th 2020

Note you shouldn't use defineAsyncComponent with lazy routes: https://next.router.vuejs.org/guide/advanced/lazy-loading.html

avatar
Nov 17th 2020

Note - Do not use Async components for routes. Async components can still be used inside route components but route component themselves are just dynamic imports.

Ah! Didn't see this. Thanks you @posva . I'd suggest a warning log or similar for this edge case.

In any case, there is a typing bug in Vue Core as the ! non-null assertion suggests that component can never be undefined.. clearly not the case ;)

avatar
Nov 18th 2020

Closing as using the proper import solves the issue. A PR for the warning with a test would be appreciated! 🙂

avatar
Nov 18th 2020

@posva wouldn't be tough... would the warning exist in vue-router or vue?

avatar
Nov 18th 2020

the warning would be on the router

avatar
Mar 19th 2021

@posva

I'm still having this problem. I'm not using Vite (yet), this is pure Vue v3.0.7.

Before I was passing a Vue.defineAsyncComponent() to the VueRouter configuration, but I already replaced that with a function that return a promise that returns the component definition.

I also am enhancing the Vue.resolveComponent = function myOwnFunction() {...} that loads the components based on the name and this is returning a Vue.defineAsyncComponent() value.

Here is a reproduction link: http://vue-next-example.arijs.org/

The error is here:

  function createAppAPI(render, hydrate) {
      return function createApp(rootComponent, rootProps = null) {
      // ... snip ...
          const app = (context.app = {
          // ... snip ...
              mount(rootContainer, isHydrate) {
                  if (!isMounted) {
                  // ... snip ...
                      return vnode.component.proxy; // <== vnode.component is null

Below is the value of vnode:

({
  "__v_isVNode": true,
  "__v_skip": true,
  "type": {
    "name": "AsyncComponentWrapper",
    "setup": setup() {
      const instance = currentInstance; // already resolved if (resolvedComp) { return () => {…
    },
    "__asyncLoader": () => {…}
    "__proto__": Object
  },
  "props": null,
  "key": null,
  "ref": null,
  "scopeId": null,
  "children": null,
  "component": null,
  "suspense": null,
  "ssContent": null,
  "ssFallback": null,
  "dirs": null,
  "transition": null,
  "el": null,
  "anchor": null,
  "target": null,
  "targetAnchor": null,
  "staticCount": 0,
  "shapeFlag": 4,
  "patchFlag": 0,
  "dynamicProps": null,
  "dynamicChildren": null,
  "appContext": null
})

Before I was getting a warning from VueRouter saying that I couldn't use Vue.defineAsyncComponent() on the routes definition. After I changed it, I'm no longer getting that warning, but somehow I still have the vnode.component is null error.