This project demonstrates a micro-frontend architecture using Vue 2 as the host application and Vue 3 applications as dynamically loaded remotes, powered by Webpack Module Federation.
It showcases seamless cross-version communication, shared state management, and routing.
-
Global Reactive Store
Manages the central user data using Vuex (Vue 2). -
Global Store Exposure
Exposes a reactive global store (users,isLoading,error) to Vue 3 remotes via a store-adapter andVue.observable. -
Shared Services
Provides:- A global EventBus for pub-sub communication
- Vue Router and Vue I18n instances
These are shared with remotes viaprovide/inject.
-
Routing
/users: Loads Vue 3 User List viaUserList.vue/edit-user/:id: Loads Vue 3 Edit User viaEditUser.vue/add-user: Loads Vue 3 Add User viaAddUser.vue
-
API Simulation
Handles events from remotes to trigger mock API actions (e.g. update, add, delete users). -
Error Handling
Implements basic error handling and loading indicators.
-
Dynamic Loading
Loaded into the host at runtime using Webpack Module Federation. -
Reactive Store Consumption
Inject thestore-adapterfrom host to listen to reactive state. -
No Direct API Calls / State Mutations
- Emit events like
remote:updateUser,remote:addUser,remote:deleteUser - Host listens, dispatches Vuex actions, updates state
- Remotes react to updated store
- Emit events like
-
Shared Service Consumption
Inject shared services:EventBus,hostRouter,i18n.
- Displays user list from host store
- Reacts to store updates
- "Edit" → navigates to
/edit-user/:id - "Delete" → emits
remote:deleteUserevent - Custom modal used for confirmation
- Receives
userIdviainject(null for add mode) - Fetches user from host's store
- Renders editable form
- On submit:
- Emits
remote:updateUserorremote:addUserevent - Host updates store + simulates API
- Remote reflects update and navigates to
/users
- Emits
├── host-app-vue2/
│ ├── public/
│ │ └── index.html
│ ├── src/
│ │ ├── assets/
│ │ ├── components/
│ │ ├── pages/
│ │ │ ├── Home.vue
│ │ │ ├── About.vue
│ │ │ ├── UserList.vue
│ │ │ ├── EditUser.vue
│ │ │ └── AddUser.vue
│ │ ├── plugins/
│ │ │ └── i18n.js
│ │ │ └── eventBus.js
│ │ ├── router/
│ │ │ └── index.js
│ │ ├── store/
│ │ │ ├── index.js
│ │ │ └── store-adapter.js
│ │ ├── utility/
│ │ │ ├── dummy-users.json
│ │ ├── App.vue
│ │ └── main.js
│ ├── package.json
│ └── webpack.config.js
├── user-app-Vue3/
│ ├── public/
│ │ └── index.html
│ ├── src/
│ │ ├── composables/
│ │ │ └── useHostStore.ts
│ │ ├── pages/
│ │ │ └── UserList.vue
│ │ ├── App.vue
│ │ └── main.ts
│ ├── package.json
│ └── webpack.config.js
├── edit-user-app-vue3/
│ ├── public/
│ │ └── index.html
│ ├── src/
│ │ ├── composables/
│ │ │ └── useHostStore.ts
│ │ ├── App.vue
│ │ └── main.ts
│ ├── package.json
│ └── webpack.config.js
# Host App
cd host-app-vue2
npm install
# Remote App 1
cd ../user-app-vue3
npm install
# Remote App 2
cd ../edit-user-app-vue3
npm install Terminal 1: Host App (Vue 2)
cd host-app-vue2
npm run start
# → http://localhost:8080Terminal 2: User List App (Vue 3)
cd user-app-vue3
npm run start
# → http://localhost:8081Terminal 3: Edit/Add User App (Vue 3)
cd edit-user-app-vue3
npm run start
# → http://localhost:8082Open http://localhost:8080 in your browser. Use the navigation to:
- View User List (
userAppVue3) - Add a user (
editUserAppVue3in add mode) - Edit a user (
editUserAppVue3in edit mode)
-
provide/injectSharing- Vue 2 provides:
store-adapter,EventBus,i18n,router - Vue 3 remotes inject these in
setup()
- Vue 2 provides:
-
store-adapter.js- Wraps Vuex store using
Vue.observable - Reactively bridges Vue 2 store to Vue 3
- Wraps Vuex store using
-
Event Communication
- Remotes emit events (
remote:updateUser, etc.) - Host listens and dispatches Vuex actions
- Remotes emit events (
-
Routing
- All navigation handled by host router
- Remotes use injected
hostRouter.push(...)
-
Passing IDs
- Host extracts
:idfrom route - Provides it via
provide - Remote uses
injectto getuserId
- Host extracts
- Check browser console for errors
- Ensure remoteEntry.js files load correctly
- Restart servers after changes to:
webpack.config.jsmain.js