NuoNuo LeRobot
NuoNuo LeRobot

Reputation: 392

State management with vue3 and webpack module federation

I'm creating an app with MFE with Vuejs3 and webpack 5 module federation. One main app made with Vue will consume other apps (should be framework agnostic) and I need to share State from my Vue shell to other apps.

I tried making a store with the Composition api but the value get only updated in the app that call the event.

Here is the store that I expose from the vue shell:

import { reactive, toRefs } from 'vue'

const state = reactive({
  data: {
    quantity: 1,
  },
})

export default function useStoreData() {
  const updateQuantity = (quantity) => {
    state.data.quantity += quantity
  }

  return {
    ...toRefs(state),
    updateQuantity,
  }
}

in vue shell :

<template>
    <div>
      <button @click="updateQuantity(1)">FOO +1</button>
      <div>Quantity = {{ data.quantity }} </div>
    </div>
</template>

<script setup>
import useStoreData from '../store/storeData'
const { updateQuantity, data } = useStoreData()
</script>

when I click on the button "FOO +1", value gets updated +1.

in my remote app:

<template>
  <div>
    <button @click="updateQuantity(5)">BAR +5</button>
    <div>Quantity = {{ data.quantity }}</div>
  </div>
</template>

<script setup>
import store from 'store/storeData'

const useStoreData = store
const { data, updateQuantity } = useStoreData()
</script>

When i click on button "BAR +5" the value get update +5

BUT everytime I click on one of those button, the value in the other app doesn't get updated.

What did I miss ?

Upvotes: 3

Views: 2661

Answers (1)

NuoNuo LeRobot
NuoNuo LeRobot

Reputation: 392

Needed to add the shell app as a remote of itself then import the store in the shell app, same way as i'm doing in my remote app.

Here is the vue.config.js of the shell, where I need to expose AND remote the store.

const { ModuleFederationPlugin } = require('webpack').container
const deps = require('./package.json').dependencies

module.exports = {
  publicPath: '/',
  configureWebpack: {
    plugins: [
      new ModuleFederationPlugin({
        name: 'shell',
        filename: 'remoteEntry.js',
        remotes: {
          test: 'test@http://localhost:8081/remoteEntry.js',
          test2: 'test2@http://localhost:8082/remoteEntry.js',
          store: 'shell@http://localhost:8080/remoteEntry.js', <= ADDED HERE the remote of itself
        },
        exposes: {
          './storeData': './src/store/storeData.js',
        },
        shared: [
          {
            ...deps,
          },
        ],
      }),
    ],
  },
  devServer: {
    port: 8080,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
      'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
    },
  },
}

In the Vue shell app:

<script setup>
// import useStoreData from '../store/storeData' <= wrong
import store from 'store/storeData' <= good
</script>

Upvotes: 3

Related Questions