Subscribe on changes!

Cannot mount an app within an app

avatar
Apr 4th 2022

Version

3.2.31

Reproduction link

sfc.vuejs.org/

Steps to reproduce

Click the 'unmount app' button

The error message will show in the Developer Tools Console

TypeError: Cannot read properties of null (reading 'nextSibling')

What is expected?

No error on app.unmount() when the fragment dom content is not exist

What is actually happening?

There is an error on app.unmount() when the fragment dom content is not exist


Combine usages of x6 and AntdVue

  1. Create a component Foo.vue which the root element is a Popover component. The AntdVue Popover component is a fragment implemented inside
  2. registerVueComponent with Foo, named this x6 node 'foo-node'
  3. Render some custom node of 'foo-node'
  4. Call removeCells of x6 to remove these nodes
  5. Show error and the x6 content area is not responsive, because x6 does not handle exception of unmount error

Maybe this error will occur in some other scenarios when app.unmount()

  1. Some browser extensions maybe clear the content of the fragment dom container
  2. In micro frontend, the sub app is a fragment, root app clear sub app dom content by mistake
avatar
Apr 4th 2022

Demo with x6 library:

Reproduction link

https://stackblitz.com/edit/vitejs-vite-nghwu9?file=README.md

Steps to reproduce

  1. click the button

What is expected?

Remove all the two custom nodes

What is actually happening?

Only remove one node

avatar
Apr 7th 2022

You cannot mount an app within an app, use a component instead or make sure you manually add an element that isn't handled by Vue

avatar
Apr 7th 2022

@posva Thanks for your reply. I know it is the best practice not to mount an app within an app. Maybe the sfc reproduction link is obfuscated.

In this https://stackblitz.com/edit/vitejs-vite-nghwu9 demo, the editable svg area is an element not controlled by vue. x6 library can be using create an svg node using vue component with foreignObject. I think the x6 node is not a part of the main vue application, they are controlled by the custom x6 instance which isn't handled by vue.

The key point is when the child nodes of the fragment container doesn't exist, unmounting the fragment instance will cause the error.

Some complex apps may be consisting with multi app instance, fake code below,

<head>
<!-- some code -->
</head>

<body>
  <div id="subapp1"></div>
  <div id="subapp2"></div>

  <script>
    const subApp1 = createApp({/* fragment component*/});
    const subApp2 = createApp({});

    subApp1.mount('#subapp1');
    subApp2.mount('#subapp2');

    document.getElementById('subapp1').innerHTML = '';

    subApp1.unmount();
  </script>
</body>

Vue will throw the error on calling unmount when subapp1 children do not exist. It's an edge case when unmount fragment.

But it would be confused when the application is complicated. Especially using some third-party libraries that use createApp internal (antd vue, vant), it's more difficult to figure out why this error occurred.

avatar
Apr 7th 2022

You are not supposed to manually manipulate the HTML that is handled by Vue either. You just need to move the html clear after the unmount like this