webpack module federation + vuejs dynamic import()

Viewed 903

I'm trying to call some components dynamically depending on the route name. My components are coming from remotes module federation so i need to keep that structure : import('module/Module') unless there are other ways to define it.

here is my webpack config

 new ModuleFederationPlugin({
      name: "core-front",
      remotes: {
        test: "test@http://localhost:8081/remoteEntry.js",
        test2: "test2@http://localhost:8082/remoteEntry.js",
      },
      exposes: {},
      shared: require("./package.json").dependencies,
    }),

So i would like to load test or test2 if my route is localhost:8080/app/test

I tried to rewrite dynamically the name and use it inside import() but it doesn't work.

<template>
  <component :is="name"></component>
</template>

<script setup>
import {computed, defineAsyncComponent} from "vue";
import {useRoute} from "vue-router";
const route = useRoute();

const capitalizer = (string) => {
  return (string && string[0].toUpperCase() + string.slice(1)) || "";
};

const name = computed(() => {
  const appName = route.params.name;
  const appNameCapitalize = capitalizer(appName);

  return defineAsyncComponent(() => import(`${appName}/${appNameCapitalize}`));
});
</script>

I get this error : Uncaught (in promise) Error: Cannot find module 'test/Test'

(the module name is right though...)

This works:

const name = computed(() => defineAsyncComponent(() => import("test/Test")));

It seems we cannot use dynamic name in import. Any idea how to bypass this issue ? I would like later to use dynamic list of exposed modules as well, that's why I don't want to hard code names.

1 Answers

if in React, use the below methods to load dynamic module, I will say they would be quite similar in VUE tho...

function loadComponent(scope, module, baseModuleType) {
   return async () => {
    await __webpack_init_sharing__('default');
    const container = window[scope];

    await container.init(__webpack_share_scopes__.default);

    const factory = await window[scope].get(module);
    const Module = factory();
    return { default: Module[baseModuleType] };
  };
}

const Component = React.lazy(loadComponent('App2', `./components/${componentsType}`, type));
<React.Suspense fallback="Loading System">
     <Component />
</React.Suspense>

If any further question, refer below:

https://webpack.js.org/concepts/module-federation/#dynamic-remote-containers

https://dev.to/waldronmatt/tutorial-a-guide-to-module-federation-for-enterprise-n5

Related