Back

Combining front-end frameworks/libraries using federated modules

10/7/2020
Radmir Gurkov

I believe almost everyone has heard of the new killer feature called federated modules. In my opinion, with this feature we can either use already written open source modules and merge them into an app or it can be useful for a big project where different teams can create independent modules. Most importantly, all examples are presented in one ecosystem only (React library).

After reading this article about micro front-ends, I decided to write a micro front-ends application with federated modules features.
My first intention was to combine React and Svelte. But I ended up struggling with Svelte loader issues and found only one solution to provide aliases and main fields to webpack config. Unfortunately, this fix didn’t work in my case (github, stack overflow) . Therefore, I gave up and went for Vue.

How to combine them with each other

As a developer, you have basically 2 options:

  1. access module from window object
  2. import module and assign to DOM element

‍

Access module from window object
‍

Access through window object property can be done easily by accessing the library name which is defined in ModuleFederationPlugin. So something like this:
src: modules/vue-module/webpack.config.js

‍

{% c-block language="js" %}
new  ModuleFederationPlugin({
   name: 'vue',
   library: { type:  "var", name:  "vue" },
   exposes: {App: './src/bootstrap'}
   ...etc
})
{% c-block-end %}

‍

Then we can access module
src: modules/main/public/index.html

‍

{% c-block language="js" %}
window.vue.get('App').then(module => {
const vueInstance = module().default;
vueInstance.$mount('#vue');
});
{% c-block-end %}

‍

Basically, we have async import from which we can take our Vue instance through default export and mount it to some element in DOM.

‍

Import module inside react component and assign it to DOM element

‍

And here comes the fun part…

For mounting the Vue component you need:

  1. useRef:
    To append the child in which we will mount the Vue instance
  2. useEffect:
    To handle the React component life cycle and provide side effects
  3. document.createElement:
    For Vue instance mount <- this explicitly defined container must be provided because when Vue is mounted it will use the container for the template render.

It will look something like this: src: modules/main/src/VueContainer.jsx

‍

{% c-block language="js" %}
import React, { useRef, useEffect } from 'react'
import app from 'vue/App';
const container = document.createElement('div');
function VueContainer() {
       const ref = useRef();
       useEffect(() => {
           const currentElement = ref.current;
           const vueInstance = app();
           if(currentElement) {
                  currentElement.appendChild(container);
                  vueInstance.$mount(container);
           }
           return () => {
                  vueInstance.$destroy();
                  container.remove();
           }
       }, [ref])
       return <div ref={ref}></div>
}
{% c-block-end %}

‍

And it works, but …

‍

‍

Rendering issues
‍

We will get the Vue instance, but the template will not receive props. Instead of a rendered component, we will get bunch of errors in which properties are defined in the template, but the instance does not have them. After several hours of searching, I found a great article about render functions in Vue. (I would like to state that I am a kind of a newbie in Vue. So, if you know better solutions, please let me know.) We need to override the default render function and explicitly provide the templates which we want to render. We will create a component with the Vue.component function which will have an inner state and which we will use. The other problem is re-rendering. Once the Vue instance is mounted, if the React component is unmounted, then the Vue component will be unmounted too and will not re-render again. So forced re-rendering should be provided. I haven’t found a better solution yet, except for a function which returns an instance of Vue on each React component mount, create a new instance and mount it to the container.

Something like this:
src: modules/vue-module/src/bootstrap.js

‍

{% c-block language="js" %}
const app = () => new Vue({
   render: function(h) {
   const renderTemplate = this._c || h;
   return renderTemplate(App); // <- App.vue
   }
});
{% c-block-end %}

‍

But this approach also has its flaws – with each re-render the Vue components lose their state

‍

‍

A few words at the end

This was a simple sandbox example of combining different frameworks and libraries. I am not sure if this could be used for production purposes, but it is a cool feature which is fun to play with and I want to explore it little bit more in the future.

Code example link

What is on my to-do list?

  • Try to combine with other frameworks / libraries
  • Find a solution to have a persistent state

Radmir is a Web and Mobile App Developer. His professional career started in 2018, but he has always been keen on learning new technologies. He has gained the most experience in Java/Typescript, React, MobX, and Express.js. He loves both music and computer games of any kind.

Show profile
SABO Mobile IT logo
SABO Mobile IT – Experience
SABO Mobile IT – Experience
SABO Mobile IT – Experience
SABO Mobile IT – Experience
SABO Mobile IT – Experience

SABO IT

SABO IT develops custom software for companies with complex technical processes, from the control unit through the cloud to enterprise systems, including in regulated environments. It also has its own platforms: SenseDrive for source-verified answers from your own knowledge base, and SABOT for voice control of machines. Software development since 1983, as SABO IT since 2012; the average customer relationship lasts 6.5 years.
ABOUT US

More articles

Artikelbild (Platzhalter)
Recommended for you

What does AI in the enterprise really cost? Why the price per user is the wrong number

Three reports from this year show why compute power is becoming a strategic question for European companies. According to Siemens board member Cedrik Neike, European data centers run 20 to 30 percent above US levels in operating costs, while companies, in his estimate, would pay only 5 to 10 percent more for it.
Guido Stanovski,  October 29, 2026
Read article

Book a meeting

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.