An issue has been encountered with the Vue Router within the Micro Front End/Web Components setup, displaying the error message: "Uncaught TypeError:

I encountered an issue that I need help with. Here is the scenario:

I have built a Vue application called my-admin micro app consisting of 4-5 screens/components (manage user, manage notifications, manage roles, etc.). I created a router.js file where I defined the following routes:

...imports... 
Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    name: 'main-layout',
    component: MainLayout,
    children:[
      {
        path : 'manage-user',
        name : 'manage-user',
        component : ManageUserComponent
      },
      {
        path : 'manage-role',
        name : 'manage-role',
        component : ManageRoleComponent
      }
    ]
  }
]

const router = new VueRouter({
  routes
})

export default router

I imported this router object in my main.js as follows:

...imports...
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

Lastly, I wrapped my micro app as a web component (MainLayout component) in main.js like so:

const myAdmin = wrap(Vue,MainLayout)

window.customElements.define('my-admin', myAdmin)

I built this micro app using the following command:

"build": "vue-cli-service build --target wc --name my-admin ./src/main.js",

This micro app runs perfectly when launched individually.

In my situation, I also have a shell application named my-shell developed in Vue. This shell application has its own vue router and is imported in its main.js as shown below:

Shell router:

...imports... 

Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    name: 'container',
    component: Container,
    children:[
      {
        path : 'admin',
        name : 'admin-microapp',
        component : AdminMicroAppContainerComponent
      },
      {
        path : 'other',
        name : 'other-microapp',
        component : OtherMicroAppContainerComponent
      }
    ]
 }
]

const router = new VueRouter({
  routes
})

export default router

I imported this router object into my-shell's main.js as follows:

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

Within my-shell's index.html file, I added script tags to load my micro apps' builds (my-admin.js file) like so:

 <script src="../assets/my-admin/dist/my-admin.js"></script>
 <script src="../assets/other-microapps/dist/micro-app.js"></script>

However, upon starting my-shell application, it throws the following error:

Uncaught TypeError: Cannot redefine property: $router. 

I am seeking advice on resolving this error. How can I fix this?

Answer №1

Although I have not attempted to replicate this specific scenario, I can easily identify the cause of its failure.

Let's briefly examine what occurs when launching a Single Page Application (SPA).

Routers are initialized at the start, such as new Vue(), and your sub-apps are connected midway during Dom Rerendering. Following this process, it becomes impossible to transition from a mid-app section back to the top without disrupting either the initial router or rejecting the new one.

Here is my suggestion:

Avoid using vue-router in your sub-applications (web components); instead, opt for a simpler routing solution.

In my experience with micro-frontends, adhering to the SOLID design principle is crucial. If your sub-applications are so complex that they necessitate vue-router for routing, then there may be an issue*.

Typically, a sub-application should focus on performing a single function.

For instance, in a business SaaS platform, a customer micro app is solely responsible for:

  1. Creating new customers (via a pop-up modal)
  2. Listing customers
  3. Viewing an individual customer's transaction report
  4. Editing customer information (via a pop-up modal)

Handling customer payments, debts, and intricate charting reports is each allocated to separate sub-applications.

Only steps 2 and 3 entail routing, which we managed using v-if statements.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Identifying when a browser is closed with multiple tabs open in Internet Explorer

I need to detect when a browser tab is closed in order to trigger a Struts action. I have successfully implemented this for a single tab using the following JavaScript code: <script type="text/javascript> function loadOut() { if ((window.event.c ...

Guide on fetching data from a database using Node Js in a hierarchical structure

I am currently developing a NodeJs backend code to retrieve data from the database. The desired structure of the data should look like this: data = [{ name: "Admin", id: '1', children: [ { name: "Admin", id: "1& ...

Exploring the Module System of TypeScript

I am working with a TypeScript module structured like this: let function test(){ //... } export default test; My goal is for tsc to compile it in the following way: let function test(){ //... } module.exports = test; However, upon compilation, ...

A mysterious property appearing in a Webpack plugin

Here is my webpack configuration file and package.json. When I execute the command webpack -w, I encounter the following error (shown below). I suspect it may be related to path strings. Any help would be greatly appreciated. webpack.config.js const HtmlW ...

What is the best way to start data in an Angular service?

I'm currently navigating my way through building my first Angular application. One of the services I am using needs to be initialized with a schema defined in its constant block, but the schema/configuration is not yet finalized. Therefore, I am perfo ...

The page switch with a jittery effect

Could really use some assistance with this code that has been giving me trouble for quite a while now. It's a simple HTML, CSS, and JS code involving two pages. [The second page overlaps the first by default, but adjusting the z-index of the first p ...

Troubleshooting: Issues with jQuery Validate plugin's rules method in Javascript

I'm encountering an issue with a simple javascript file that is supposed to run the rules method, but it's not working as expected. I have confirmed that my custom javascript file is being rendered correctly since input masking is functioning pro ...

Tips for implementing daterangepicker js in an Angular 2 project

I'm currently working on an Angular 2 project and I'm looking to integrate the daterangepicker.js library for a date range picker. If you're not familiar with it, you can find more information about the library here. Here's the HTML co ...

Getting rid of the border next to v-navigation-drawer in Vue.js

I need help removing a persistent thin line on the left of my navigation drawer that I created without borders. Despite trying to remove it using border : none, the line remains there. Upon inspecting the element, I discovered that the issue lies in a spe ...

Discovering the Nearest Point to the Mouse Cursor using Three JS Ray Casting

Three.js version r85 While using raycasting in Three JS, a list of points is generated, and I am interested in identifying the point closest to the cursor. It appears that the first point returned is typically the one nearest to the camera. Is there a me ...

I'm looking for some help with creating a visualization using JavaScript or Python. Can anyone offer some guidance?

// Defining the dimensions and margins of the graph var width = 460 var height = 460 // Appending the svg object to the body of the page var svg = d3.select("#my_dataviz") .append("svg") .attr("width", width) .attr("height", height) // Reading ...

Webpack is having trouble resolving the specified file or directory

MyAPP: |--src   |--index.js   |--content.js |--webpack.config.js index.js : const React = require('react'); const ReactDom = require('react-dom'); const View = require('./content'); ReactDom.render(<View/ ...

I am facing an issue with Angular where the $http.get method is

It seems like there must be a small oversight causing this apparently simple problem. I have a function that interacts with the Spotify API to search for an artist. I know that by accessing the corresponding route using a standard URL, a result is returne ...

Monitor the closure of a programmatically opened tab by the user

Currently, I am in the process of developing a web application using Angular 11 that interacts with the msgraph API to facilitate file uploads to either onedrive or sharepoint, and subsequently opens the uploaded file in the Office online editor. Although ...

How can I create a table using a loop and an onclick function for each <td>?

I have written code to create a table in PHP using a loop. I want to add an onclick function to each cell so that when a particular cell is clicked, the background color changes. However, I am encountering an error. Am I doing something wrong? <head& ...

Changing $scope does not automatically refresh the selected option when using ng-options with <select> in AngularJS

My select element is structured like this: <select ng-model="exportParam" ng-options="item as item.lib for item in allExportParams | orderBy:'lib'" class="form-control"> </select> To save its state for later display, I sto ...

The perplexing behavior of RxJS Observables with Mongo Cursors

Recently, I've been working on converting a mongo cursor into an observable using my own RxJS implementation. Despite finding numerous solutions online, I wanted to challenge myself by creating one from scratch. I would greatly appreciate it if someo ...

Is it possible to arrange a react map based on the length of strings?

I am working on a React function that loops through an object and creates buttons with text strings retrieved from the map. I want to display the text strings in order of their length. Below is the code snippet for the function that generates the buttons: ...

Executing a POST Request using a Custom Node Module in Express

I'm in the process of developing a web application where the user inputs their username, submits it, and then the application processes the input through a POST request to another server. Based on the response from the external server, the user is red ...

Synchronizing a parent object's property with its child components in Vue

The Background Currently, I am working on constructing a large form with numerous inputs in Vue.js 2.6.10 using class-based components in Typescript 3.5.3. To prevent overwhelming the user, the form is divided into multiple components where only one compo ...