Parcel ends up duplicated in the body of the document if props are updated
Demonstration
This is the repository to reproduce the issue: https://github.com/fcano-ut/single-spa-test
In the repo you can start three servers:
- react-microfrontend (to test using a microfrontend)
- angular-host (where the issue happens)
- react-host (to check that the issue does not happen there, so it must be due to this package and not something about the microfrontend)
The key to reproduce the issue is to first mount the parcel, and then update any of it's props. I'm using this code in the Angular host (https://github.com/fcano-ut/single-spa-test/blob/main/packages/angular-host/src/app/app.component.ts#L13-L29)
export class AppComponent {
title = 'angular-host';
public customProps: any = {
message: "I'm passing a prop on mount!"
};
// ...
ngOnInit() {
// ...
window.setTimeout(() => {
this.customProps = {
message: "I'm updating props!",
};
}, 100);
The react microfrontend simply prints the message like so: {props.name} is mounted! and it's saying: {props.message}
If we load this in the browser, it's clear that the microfrontend loads twice, the second time at the end of the page:

If we stop exporting the update function on the microfrontend side (removing it from here), it loads only where it should, but it doesn't receive updates on props.
Also we can just stop updating props to get the same result, it renders correctly but you cannot update props:

Meanwhile, the React host works correctly as it should, so I assume the issue is in the Angular Parcel component
https://github.com/single-spa/single-spa-angular/assets/97605542/6c04f11e-2465-4cbe-bee8-b9accde2269b
Expected Behavior
I expect the Angular host app to work as the React host app: first load the microfrontend, then update it in place
Actual Behavior
The Angular host first renders the microfrontend with initial props where it should, but then updates it and duplicates the microfrontend, appending it to the end of the body component, with the new props. Two versions of the microfrontend end up in the page.
(I didn't include this in the reproduction example, but in our real world scenario we also have navigation using Angular router, and the duplicated microfrontend doesn't unmount when the route changes)
Just for future reference, this was first included as an issue in the single-spa-react package, but that issue was closed when I found out the cause of the issue is here. The previous issue was: https://github.com/single-spa/single-spa-react/issues/194