@cesarchamal/single-spa-vue-app
v1.0.18
Published
Vue application with two example pages for be included in a single-spa application as registered app.
Downloads
68
Maintainers
Readme
single-spa-vue-app
Part of Demo Microfrontends - A comprehensive Single-SPA microfrontend architecture demonstration
A Vue.js 2 microfrontend for Single-SPA demonstrating progressive framework features, reactive data binding, and component-based architecture.
🏗️ Microfrontend Architecture
This application is one of 12 microfrontends in the demo-microfrontends project:
| Microfrontend | Framework | Port | Route | Repository | |---------------|-----------|------|-------|------------| | 🎯 Root App | Single-SPA | 8080 | Orchestrator | single-spa-root | | 🔐 Auth App | Vue.js | 4201 | /login | single-spa-auth-app | | 🎨 Layout App | Vue.js | 4202 | All routes | single-spa-layout-app | | 🏠 Home App | AngularJS | 4203 | / | single-spa-home-app | | 🅰️ Angular App | Angular 8 | 4204 | /angular/* | single-spa-angular-app | | 💚 Vue App | Vue.js 2 | 4205 | /vue/* | This repo | | ⚛️ React App | React 16 | 4206 | /react/* | single-spa-react-app | | 🍦 Vanilla App | ES2020+ | 4207 | /vanilla/* | single-spa-vanilla-app | | 🧩 Web Components | Lit | 4208 | /webcomponents/* | single-spa-webcomponents-app | | 📘 TypeScript App | TypeScript | 4209 | /typescript/* | single-spa-typescript-app | | 💎 jQuery App | jQuery 3.6 | 4210 | /jquery/* | single-spa-jquery-app | | 🔥 Svelte App | Svelte 3 | 4211 | /svelte/* | single-spa-svelte-app |
Main Repository: demo-microfrontends
Features
- Vue.js 2: Progressive JavaScript framework
- Vue Router: Client-side routing with navigation guards
- Vuex: Centralized state management (optional)
- Single File Components: Template, script, and style in one file
- Reactive Data Binding: Automatic UI updates
- Component Composition: Reusable and composable components
Technology Stack
- Framework: Vue.js 2.6.11
- Router: Vue Router 3.1.4
- Build Tool: Vue CLI 4 with library target
- Language: JavaScript (ES2015+)
- Integration: Single-SPA Vue adapter
Development
Prerequisites
- Node.js (v18.0.0 or higher)
- npm (v8.0.0 or higher)
Installation
npm installDevelopment Server
npm start
# Runs on http://localhost:4205Build
npm run build
# Outputs to dist/single-spa-vue-app.umd.jsVue.js Features
Single File Components
<template>
<div class="feature-component">
<h2>{{ title }}</h2>
<button @click="handleClick">{{ buttonText }}</button>
</div>
</template>
<script>
export default {
name: 'FeatureComponent',
data() {
return {
title: 'Vue Feature',
buttonText: 'Click Me'
};
},
methods: {
handleClick() {
this.$emit('feature-clicked');
}
}
};
</script>
<style scoped>
.feature-component {
padding: 20px;
}
</style>Reactive Data System
export default {
data() {
return {
message: 'Hello Vue!',
items: []
};
},
computed: {
filteredItems() {
return this.items.filter(item => item.active);
}
},
watch: {
message(newVal, oldVal) {
console.log(`Message changed from ${oldVal} to ${newVal}`);
}
}
};Component Communication
// Parent to Child (Props)
<child-component :data="parentData" />
// Child to Parent (Events)
this.$emit('update-data', newData);
// Sibling Communication (Event Bus)
this.$bus.$emit('global-event', data);Single-SPA Integration
This microfrontend exports the required Single-SPA lifecycle functions:
export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;Mount Point
The application mounts to the DOM element with ID vue-app:
<div id="vue-app"></div>Route Configuration
Configured to activate on routes starting with /vue:
singleSpa.registerApplication(
'vue',
() => loadApp('single-spa-vue-app'),
showWhenPrefix(['/vue'])
);Vue Router Integration
export default new Router({
mode: 'history',
base: '/vue',
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/contact', component: Contact }
]
});Vue Configuration
External Dependencies
The application uses webpack externals for shared dependencies:
config.externals([
'vue',
'vue-router',
'single-spa-vue'
]);Library Build
Built as UMD library for Single-SPA consumption:
configureWebpack: {
output: {
library: 'single-spa-vue-app',
libraryTarget: 'umd',
filename: 'single-spa-vue-app.js'
}
}Component Architecture
Page Components
<!-- Home.vue -->
<template>
<div class="home-page">
<hero-section />
<feature-list :features="features" />
<call-to-action @action-clicked="handleAction" />
</div>
</template>
<script>
import HeroSection from '@/components/HeroSection.vue';
import FeatureList from '@/components/FeatureList.vue';
import CallToAction from '@/components/CallToAction.vue';
export default {
name: 'Home',
components: {
HeroSection,
FeatureList,
CallToAction
},
data() {
return {
features: []
};
},
async created() {
this.features = await this.fetchFeatures();
}
};
</script>Reusable Components
<!-- FeatureCard.vue -->
<template>
<div class="feature-card" :class="{ active: isActive }">
<slot name="icon"></slot>
<h3>{{ title }}</h3>
<p>{{ description }}</p>
<button @click="$emit('select', feature)">
Select Feature
</button>
</div>
</template>
<script>
export default {
name: 'FeatureCard',
props: {
feature: {
type: Object,
required: true
},
isActive: {
type: Boolean,
default: false
}
},
computed: {
title() {
return this.feature.title;
},
description() {
return this.feature.description;
}
}
};
</script>State Management
Component State
export default {
data() {
return {
loading: false,
error: null,
data: []
};
},
methods: {
async fetchData() {
this.loading = true;
this.error = null;
try {
const response = await fetch('/api/data');
this.data = await response.json();
} catch (error) {
this.error = error.message;
} finally {
this.loading = false;
}
}
}
};Vuex Integration (Optional)
// store/index.js
export default new Vuex.Store({
state: {
user: null,
preferences: {}
},
mutations: {
SET_USER(state, user) {
state.user = user;
}
},
actions: {
async fetchUser({ commit }) {
const user = await api.getUser();
commit('SET_USER', user);
}
}
});File Structure
single-spa-vue-app/
├── src/
│ ├── components/ # Reusable components
│ ├── views/ # Page components
│ ├── router/ # Vue Router configuration
│ │ └── index.js # Router setup
│ ├── store/ # Vuex store (optional)
│ ├── assets/ # Static assets
│ ├── App.vue # Root component
│ └── singleSpaEntry.js # Single-SPA integration
├── dist/ # Build output directory
├── package.json # Dependencies and scripts
├── vue.config.js # Vue CLI configuration
├── .gitignore # Git ignore rules
└── README.md # This fileVue CLI Configuration
Library Build Setup
// vue.config.js
module.exports = {
configureWebpack: {
output: {
library: 'single-spa-vue-app',
libraryTarget: 'umd'
},
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
})
]
},
chainWebpack: config => {
config.externals(['vue', 'vue-router', 'single-spa-vue']);
}
};Development Configuration
- Hot module replacement
- Source maps
- ESLint integration
- SCSS preprocessing
Styling Architecture
Scoped Styles
<style scoped>
.component {
/* Styles scoped to this component */
}
</style>Global Styles
<style>
/* Global styles */
.utility-class {
margin: 0;
}
</style>CSS Modules
<style module>
.title {
font-size: 2rem;
}
</style>
<template>
<h1 :class="$style.title">Title</h1>
</template>Performance Optimization
- Bundle Size: ~235KB (UMD build)
- Tree Shaking: Unused code elimination
- Lazy Loading: Route-based code splitting
- Component Caching: Keep-alive optimization
Vue Devtools
Development Features
- Component inspector
- Vuex state management
- Event timeline
- Performance profiling
Production Debugging
- Component hierarchy
- Props and data inspection
- Event tracking
- Time-travel debugging
Testing
Unit Tests
npm run test:unitComponent Tests
npm run test:componentsE2E Tests
npm run test:e2eLinting
npm run lintBrowser Support
- Modern browsers (ES2015+)
- IE9+ with polyfills
- Mobile browsers
- Progressive enhancement
Migration Path
Vue 2 to Vue 3
- Composition API preparation
- Breaking changes assessment
- Gradual migration strategy
- Compatibility considerations
Contributing
- Fork the repository
- Create a feature branch
- Follow Vue.js style guide
- Add tests for new components
- Ensure accessibility compliance
- Submit a pull request
License
MIT License - see LICENSE file for details.
Related Projects
- Vue.js - Progressive JavaScript framework
- Vue Router - Official router for Vue.js
- Vuex - State management pattern + library
- Single-SPA - Microfrontend framework
- Demo Microfrontends - Complete microfrontend demo
🚀 Quick Start
Run the complete microfrontend system:
# Clone main repository
git clone https://github.com/cesarchamal/demo-microfrontends.git
cd demo-microfrontends
# Start all microfrontends
./run.sh local devRun this microfrontend individually:
npm install
npm start
# Visit http://localhost:4205Author
Cesar Francisco Chavez Maldonado - Vue.js 2 Microfrontend Example
