This is the problem which I have been trying to solve from day 1 ever since I started using VueJS. I will not consider a client side JS framework if it does not provide a solution for this problem.
I recently did a PoC in this and able to consume a VueJS application as module in another VueJS application. In my case I have a suite of VueJs applications where each of these applications is running in its own dedicated docker container. These applications have a lot of functionality which is common across all the applications. So I decided to move this common code (page layout, css frameworks etc) to a separate VueJS application and consume all existing VueJS applications as modules in this global application. I call this micro-app based architecture to differentiate it from micro-frontends based architecture because it does not use multiple client side JS frameworks and does not require another framework to achieve this. This is how the deployment architecture looks like in my case (you can ignore kubernetes specific stuff if your are not aware about it) -

Coming back to implementation part, you need to take a step wise approach to convert a VueJS application to a micro-app.
- Lets say you project structure look as following (it shows only few files which require changes and NOT all the files) -
app-1
public
index.html
src
main.js
App.vue
router
index.js
store
index.js
- Split your vuex state and routes files into global and application specific files -
app-1
public
index.html
src
main.js
App.vue
router
app1
index.js
index.js
store
app1
index.js
index.js
- Make a copy of this project (global-app), remove
global-app specific files from app-1 and app-1 from specific files from global-app. Also remove index.html and App.vue from app-1 project -

- Add
ROUTES and STORE_MODULES variables to index.html file of global-app -
<head>
....
....
<script type="text/javascript">
const ROUTES = []
const STORE_MODULES = {}
</script>
</head>
<body>
....
....
<div id="app"></div>
<script type="text/javascript" src="/app1/micro-app.umd.min.js"></script>
<!-- built files will be auto injected -->
</body>
- Update
router\index.js file of global-app for ROUTES variable -
const routes = [
....
....
]
routes.push(...ROUTES)
const router = new VueRouter({
- Update
store\index.js file of global-app for STORE_MODULES variable -
export default new Vuex.Store({
....
....
modules: STORE_MODULES
})
- Clear content of
app-1\src\main.js file and replace it with following content -
import routes from '@/router/app1'
import app1 from '@/store/app1'
ROUTES.push(...routes)
STORE_MODULES['app1'] = app1
- Define
build-app command under scripts block of package.json file of app-1 -
....
"scripts": {
"build-app": "vue-cli-service build --target lib --formats umd-min --no-clean --name micro-app src/main.js"
},
....
- Now build and deploy these two applications in their dedicated containers and update nginx conf file of proxy container to forward requests to these containers as following -
location / {
proxy_pass http://global-app:80;
}
location /app1/ {
proxy_pass http://app1:80/;
}
- You can access global app by using IP address and port of nginx container.
I hope I have included all the steps which are required to implement micro-app based architecture. You can refer following git repositories which were created as part of this PoC -
https://github.com/mechcloud/large-app-docker
https://github.com/mechcloud/large-app
https://github.com/mechcloud/large-app-plugin1
While I am not an expert in the internals of client side JS frameworks, I believe this approach will work for other JS frameworks (Angular, React etc) as well.