DEV Community

AK DevCraft
AK DevCraft Subscriber

Posted on • Updated on

Integrate Web Component/MFE with plain static HTML

Introduction

In an ideal world, we’d never need a hybrid solution where a modernized tech stack integrates with a legacy system. But do we really live in an ideal world?! More often than not, I’ve found myself in situations to implement a hybrid solution. I’m sure most of you have heard about micro-frontends (MFE) and how module federation is a fantastic solution. But do you know how to integrate MFE with a plain static HTML page without worrying about version updates? In other words, how can you avoid updating the consumer HTML page every time the MFE changes? I will walk you through some simple code changes that might change your life (for the better 😉).

Getting Started

Using the SystemJS library we can seamlessly integrate a web component or MFE, or even import any module at runtime.

Step 1: Export Your Module as a Map

First, using a module bundler like Webpack, export the module as a map in JSON format. The webpack-import-map-plugin makes it easy to generate the import map file.

// with a Webpack 4 config like:
config.entry = { entryName: 'entry-file.js' };
config.output.filename = '[name].[contenthash:8].js';

// Add to plugins
new ImportMapWebpackPlugin({
    filter: x => {
        return ['entryName.js'].includes(x.name);
    },
    transformKeys: filename => {
        if (filename === 'entryName.js') {
            return 'mfe-module/out-file';
        }
    },
    fileName: 'import-map.json',
    baseUrl: 'https://super-cdn.com/'
});
// output import-map.json
{
    "imports": {
        "mfe-module": "https://super-cdn.com/entryName.12345678.js"
    }
}
Enter fullscreen mode Exit fullscreen mode

Note: The above code snippet is sourced from the webpack-import-map-plugin repository

Step 2: Load SystemJS

Next, load the SystemJS file by importing it as a regular JavaScript file. You can host the file version from s.min.js on your own CDN or use an existing hosted version.

<script src="https://cdn.jsdelivr.net/npm/systemjs/dist/system.min.js"></script>
Enter fullscreen mode Exit fullscreen mode

Step 3: Import the Map JSON File

Now, import the map JSON file so your module can be integrated into the HTML page. The import map eliminates the need for hardcoding JS file paths and its version number, allowing updates to your imported module without requiring consumer code changes.

<script type="systemjs-importmap" src="/path/to/module-importmap.json">
Enter fullscreen mode Exit fullscreen mode

Note: Use the crossorigin attribute if loading from a different origin.

<script crossorigin type="systemjs-importmap" src="/path/to/import-map.json">
Enter fullscreen mode Exit fullscreen mode

Import map file example:

{
    "imports": {
        "mfe-module": "https://super-cdn.com/entryName.12345678.js"
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Load Your Module

By this point, SystemJS is loaded and it has imported the MFE/web component module. Now, it's time to load your module:

<script crossorigin>
    System.import('mfe-module');
</script>
Enter fullscreen mode Exit fullscreen mode

Once imported, you can invoke your module based on its type, whether it's a web component or a regular HTML tag that is bootstrapped:

//web component
<mfe-module/>
//some regular HTML tag that is bootstrapped.
<div id="mfe-module" />
Enter fullscreen mode Exit fullscreen mode

Conclusion

By following these steps, you can seamlessly integrate micro-frontends or web components into a legacy system without worrying about frequent updates or version management. Using SystemJS and import maps allows you to dynamically load and manage modules, ensuring that your static HTML pages stay up-to-date with minimal effort. This approach provides a scalable and efficient solution for bridging modern micro frontends with existing systems, enabling a smoother transition and continued flexibility in your architecture.

If you have reached here, then I made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or ask for any corrections.

My Other Blogs:

Top comments (0)