originjs/vite-plugin-federation

Caching Issue with `remoteEntry.js` in Vite Module Federation - Forces Users to Clear Browser Cache

skkadium opened this issue · 2 comments

We are facing a significant issue in production with Vite's Module Federation setup. When deploying new features to our microfrontend (MFE) applications, the browser caches the remoteEntry.js file. As a result, users continue to load outdated code even after a deployment. The issue is only resolved after the users manually clear their browser cache, which is causing a poor user experience in production environments.

Environment:

  • Vite version: 5.2.0
  • @originjs/vite-plugin-federation: 1.3.6
  • React: 18.2.0
  • Deployment Environment: EKS (Elastic Kubernetes Service)

Steps involved:

  • Configure a microfrontend (MFE) setup using Vite and the @originjs/vite-plugin-federation.
  • Deploy the application to EKS.
  • Make changes to one of the MFEs and redeploy.
  • Reload the browser and observe that the remoteEntry.js file is still cached, causing the application to use outdated code.
  • Clear the browser cache and refresh the page.
  • The updated features are only visible after clearing the cache.

What We Tried:
We attempted the following cache-busting techniques, but the issue persists:

  1. Nginx Configuration:

Added the following to our nginx.conf to prevent caching:

location /remoteEntry.js {
    # Tell the browser not to cache this file
    add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
    add_header Pragma "no-cache";
    expires off;
}
  1. HTML Meta Tags:

Added these meta tags in index.html to control browser caching:

<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

Despite these efforts, the browser continues to cache the remoteEntry.js file, and users do not see the updated code until they clear their cache.

  1. Vite.config.ts (Sample)
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import svgr from 'vite-plugin-svgr'
import federation from '@originjs/vite-plugin-federation'

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => ({
  base: config.webApp.path,
  plugins: [
    react(),
    svgr(),
    federation({
      name: config.appName,
      filename: 'remoteEntry.js',
      remotes: {
        'remotes/mfe1': "/mfe1/assets/remoteEntry.js",
        'remotes/mfe2': "/mfe2/assets/remoteEntry.js",
        'remotes/mfe3': "/mfe3/assets/remoteEntry.js"
      },
      exposes: {
        './App': './src/components/app'
      },
      shared: ['react', 'react-dom', 'zustand', '@tanstack/react-query', 'axios']
    })
  ],
  build: {
    modulePreload: false,
    target: 'esnext',
    minify: false,
    cssCodeSplit: false
  }
}))

Impact:
This issue is affecting production environments where users are unable to access new features immediately after deployment. It forces them to clear their browser cache manually, which is not a viable solution.

Request:
We are seeking guidance or solutions from the Vite team on how to handle cache invalidation for remoteEntry.js when using the Vite Module Federation plugin. Specifically:

  • Are there recommended strategies or configurations to ensure that remoteEntry.js always loads the latest version after a deployment?

  • Is this a known issue with the @originjs/vite-plugin-federation, and if so, are there any fixes or workarounds available?

Any assistance or advice would be greatly appreciated.

Additional Context:
Our use case involves multiple microfrontends communicating through Module Federation, with all components built using Vite and deployed to EKS. This issue is critical as it directly impacts the user experience in production.

Since I didn't find any options to add a hash to filename, during the build I will take a variable from the pipeline (CI_COMMIT_SHA)

federation({
   filename: `${name}-${import.meta.env.CI_COMMIT_SHA}.js`,
   // Or as a "hack" solution you can use timestamp
   filename: `${name}-${Date.now()}.js`,
})

See #634
Add some query to remoteEntry.js
Eg: https://remote.com/remoteEntry.js?v=17282939