Skip to content

Use vfm in a microfrontends context #466

@jorinho

Description

@jorinho

I don't report that as a bug, because it's really a specific usecase that I'm having here and I found a workaround.

This might just help the next one having the same "issue" :)

The context

I'm using vfm in a big application splitted in about 30 microfrontends (with single-spa), some of them exposing parcels, some of them using parcels from others, etc.

We have a shared library that provides UI components and re-exports app-wide utilities like vue-final-modal.

In the microfrontends that need modals, we will init the vue-final-modal when they are loaded by the main single-spa root app.

The problem

If one microfrontend uses modals, and uses as well a parcel of another microfrontend that also uses modals, the vue-final-modal initialization is done twice. The createVfm call is done twice, and while it's not a big issue if you're not playing with dynamic modals, it becomes tricky if you use the ModalsContainer and the useModal() composable.

At some point, one of the activeVfm instance was holding the dynamic modals, and the other one was holding the modalContainers :)

The workaround

To workaround this very edge case, I did this in my initialization function:

export const initVfm = (app: App) => {
  let vfm
  try {
    vfm = useVfm()

    // in prod context, if vfm is not defined, the app won't throw
    if (!vfm) {
      vfm = createVfm()
    }
  } catch (e) {
    // in non-prod context, the app will throw if no vfm is defined.
    vfm = createVfm()
  } finally {
    app.use(vfm)
  }
}

That's not super clean, but it does the work and ensure at all costs that only one vfm will ever be initialized on the page.

Again, I insist, this is useful only in a microfrontend context, when vue-final-modal is shared between all microfrontends.

Hope it can help someone, someday :)
Cheers.

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