Conquering Microfrontend Chaos: The Vue 3 Compatibility Quest

When I first joined the company, I was excited to dive into our micro frontend architecture. Our team was in the middle of refactoring the sidenav and integrating it with our design system. The only hitch? Our UI library was built using Vue 3, but some of our projects were still stuck on older versions, which weren’t compatible with Vue 3. The sidenav, a core component across all our products, suddenly became a major headache.

The initial solution seemed simple enough: use pure JavaScript to build the sidenav and export it as a standalone file. At first, this worked well. But as we started adding more features, issues began to crop up—things like animations and dropdowns that other libraries had already solved.

The Lightbulb Moment

It was one of those late nights when I had a thought: “Why not create a script that could convert our Vue 3 component into pure JavaScript?” This way, we could break through the compatibility barrier and even integrate other libraries, like those handy dropdowns.

I decided to put this idea to the test. I set out to rebuild the project and see if I could make it work. And it did! The solution not only solved our compatibility issues but also opened up new possibilities for our microfrontend architecture.

Getting My Hands Dirty

Let me walk you through how I did it. If you want to check out the final project, you can find it in the GitHub repository.

Preparations: Before diving in, make sure you have Node.js and the Vue CLI installed. If you already have Vue CLI, ensure it’s updated to version 4.5.11 or higher.

npm install -g @vue/cli

Creating a Vue 3 Project:

We’ll start by creating a Vue 3 project and a sidenav component that leverages Quasar, a UI library for Vue 3.

vue create sidenav-vue3
cd vue3-project

Installing Quasar:

vue add quasar

Building the Sidenav Component:

Here’s how the SideNav.vue component looks:

<template>
  <q-drawer show-if-above :value="true" class="bg-primary text-white">
    <q-list>
      <q-item clickable v-ripple>
        <q-item-section>Item 1</q-item-section>
      </q-item>

      <q-item>
        <q-item-section>Item 2</q-item-section>
        <q-menu anchor="top end" self="top start">
          <q-list class="bg-primary">
            <q-item clickable class="bg-primary text-white">
              <q-item-section>Sub-item 1</q-item-section>
            </q-item>
            <q-item clickable class="bg-primary text-white">
              <q-item-section>Sub-item 2</q-item-section>
            </q-item>
            <q-item clickable class="bg-primary text-white">
              <q-item-section>Sub-item 3</q-item-section>
            </q-item>
          </q-list>
        </q-menu>
      </q-item>

      <q-item clickable v-ripple>
        <q-item-section>Item 3</q-item-section>
      </q-item>
    </q-list>
  </q-drawer>
</template>

<script>
export default {
  name: 'SideNav',
  props: {
    drawer: Boolean
  },
  computed: {
    drawerModel: {
      get() {
        return this.drawer;
      },
      set(value) {
        this.$emit('update:drawer', value);
      }
    }
  }
}
</script>

<style lang="scss">
.q-drawer {
  .q-item {
    &:hover {
      background-color: rgba(255, 255, 255, 0.1);
    }
  }

  .q-btn-dropdown {
    .q-item {
      &:hover {
        background-color: rgba(255, 255, 255, 0.2);
      }
    }
  }
}
</style>

Transpiling to Pure JavaScript

Instead of manually converting the Vue 3 component to pure JavaScript, we can leverage Vue’s build targets. Here’s how you can do it in the vue.config.js file:

const { defineConfig } = require('@vue/cli-service');

module.exports = defineConfig({
  transpileDependencies: ['quasar'],
  pluginOptions: {
    quasar: {
      importStrategy: 'kebab',
      rtlSupport: true,
    },
  },
  configureWebpack: {
    entry: {
      sidenav: './src/components/SideNav.vue',
    },
    output: {
      filename: '[name].js',
      libraryExport: 'default',
    },
  },
  productionSourceMap: false,
});

This configuration tells the Vue CLI to compile the Vue 3 component into a pure JavaScript file, making it usable even in projects that aren’t Vue 3 compatible.

Conclusion

Solving compatibility issues in micro frontends can feel like navigating a maze. But with creativity and the right tools, it's possible to break through the barriers. By using the build target capabilities of the Vue CLI, I was able to ensure that our Vue 3 components could be seamlessly integrated into various projects, no matter the framework.

With this approach, you’ll be better prepared to tackle the challenges of developing micro frontends with Vue 3 components in incompatible projects. And remember, always keep experimenting and pushing the boundaries of what’s possible.