3

I need help with configuration of build/distribution of a microfrontend app that uses Vuex, Vue-Router and Vue i18n.

TL;DR: I'm having issues building a microfrontend app that will be imported in already existing systems. Our team tried to build the app as a webcomponent via "vue-cli-service" and "@vue/web-components-wrapper", but both approaches failed since the build entrypoint must be a .vue file (a Vue Component) and we cannot inject Vuex / Vue Router and Vue i18n as vue instance options inside a .vue file. We have also tried building as a lib, but it errors when loading the chunks.

In a nutshell, the team I work with is creating an isolated app that aims to be injectable on already existing systems. Since the app must be agnostic to technology, the team chose to make use of a microfrontend architecture with vue as the framework of choice. The app uses Vuex and Vue Router to handle internal data and navigation, and the data provided by the user on the different modules of the application is sent to an api to be processed and stored.

The project was created using Vue CLI and the objective was to wrap the app on a web component that could be imported and used on other systems. The issue is that, when building for production, vue-cli-service requires the entrypoint for the webcomponent build target to be a .vue file (https://cli.vuejs.org/guide/build-targets.html#web-component), but this makes us unable to inject vuex, vue-router and i18n configuration since we cannot create a new vue instance.

We have also tried to use “@vue/web-component-wrapper” to define a web-component on main.js, but that doesn’t work since the vue instance (new Vue) does not define rendering or templating. This approach also requires the entrypoint to be a .vue file or component constructor.

Currently, we are trying to export the module as a lib, which should return the Vue Instance (still unmounted), that could then be mounted on a div defined by the consumer, but the consumer errors when loading the bundle chunks. I believe this might be becauser there is not publicPath configured on the vue.config file, but we cannot make such configuration since app should be completely agnostic as to where it is used.

Here are the base project files

main.js

import Vue from 'vue'
import store from './store'
import App from './App.vue'
import router, { setNavigationRoutes } from './router-config'
import { setI18nInstance, userLanguage } from './I18n'

Vue.config.productionTip = false

const init = async () => {
  const i18n = await setI18nInstance(userLanguage)
  store.commit('SET_TRANSLATION_REF', i18n)
  setNavigationRoutes()

  return new Vue({
    store,
    router,
    i18n,
    render: h => h(App),
  })
}

export default init()

App.vue

<template>
  <div id="app">
    <home />
    <router-view />
  </div>
</template>

<script>
import Home from '@/views/Home'

export default {
  components: {
    home: Home,
  }
}
</script>
<style lang="scss">
@import './styles/style.scss'
</style>
  • Got any luck on this? – Green Wizard Jun 21 '20 at 09:24
  • @GreenWizard Yes, we ended up building the project as a lib using webpack with VueLoaderPlugin and style-loader for vue and sass files, respectively, since the project is inside a shadow dom. A LOT of the project has changed since then, so If you still require assistance send me a message and I'll try to give you a hand – Marcos de Andrade Jun 23 '20 at 21:51

0 Answers0