3

I'm building a Micro Frontend app based on Vue using Module Federation with Vite with the following structure:

Vue Host app:

  • has a vue-router that will load the required micro frontends.
  • the router has a base url named "/app".
  • The path "/login" is loading properly the micro frontend (a Vue view) exported with Module Federation.

Vue Child app:

  • This is loaded inside the host when accesing the "/login" route.
  • has another vue-router for the internal navigation
  • the base url is different to the host app.

The problem is that, when I try to navigate to different views inside the child app using router-link or "router.push", the Host app is updating the URL, and not the Child app.

This is how I expose the view from the child app:

federation({
      name: 'login-mf',
      filename: 'loginEntry.js',
      exposes: {
        './LoginMF': './src/views/Login.vue',
      },
      shared: ["vue"]
    })

This is the View I expose:

<template>
<p>Login view</p>
  <router-link to="LoginForm">Login</router-link>
  <router-link to="TestView">TestView</router-link>
  <router-view></router-view>
</template>

And the routes:

const routes = [
    { path: '/', redirect: "/form" },
    { path: "/form", component: Login },
    { path: '/test/:id', name: "TestView", component: Test },
]

const router = createRouter({
    history: createWebHistory("/login"),
    routes,
})

In the host app I get the code exposed like this:

federation({
      name: "host",
      filename: "loginEntry.js",
      remotes: {
        "login-mf": {
          external: "http://localhost:5005/assets/loginEntry.js",
          format: 'esm',
          from: 'vite'
        },
      },
      shared: ["vue", "vue-router"]
    })

And set the router like this:

const LoginMF = () => import("login-mf/LoginMF")

const routes = [
    {path: "/", component: HelloWorld },
    { path: '/login', component: LoginMF },
]

const router = createRouter({
    history: createWebHistory('/app/'),
})

How can I get the internal navigation of the internal app to work properly? Is there a way to "scope" the routers?

Ismael Ordás
  • 370
  • 4
  • 12
  • I'm quite sure you can't have nested url-based routers. This is an edge case that would make a router much more complicated, so you're on your own. You can come up with some custom wrapper that will provide a subset of vue router functionality and will handle path suffixes, e.g. for route definitions, `push`, etc – Estus Flask Jul 08 '22 at 16:06
  • 1
    The idea is to have two level routing: a main router in the host app and then each micro-frontend can have internal routing. But not sure if this can be done this way. – Ismael Ordás Jul 10 '22 at 10:23
  • Not really, at least without deeply modifying the way Vue router works. Probably could be achieved with custom strategy insteadof createWebHistory, but that's not for sure, could be something in router core too. In this case a microfrontend is an antipattern, it makes the life more difficult. Proceed from the fact that a module needs to integrate with top-level router in some way to handle its own routes – Estus Flask Jul 10 '22 at 10:53

0 Answers0