Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WP5 Module Federation: remoteEntry.js caching

With Webpack 5 module federation if remote entry is modified, you don't need to redeploy main module/application and the newest version of the module will be loaded when it's requested by the browser.

I'm wondering: since the remote URL remains the same (e.g. http://localhost:8081/remoteEntry.js), the browser probably will cache the file and cached version loaded every time you load the main module. On the other hand, if you add cache busting for remote entries, you will not have caching.

Let's assume that there is an application with micro-frontend architecture using Webpack 5 Module federation. There is a remote micro frontend with a config like:

output: {
  publicPath: "http://localhost:8081/",
},
plugins: [
  new ModuleFederationPlugin({
    name: "app1",
    filename: "remoteEntry.js",
    exposes: {
      "./Component1": "./src/Component1",
      "./someModule1": "./src/someModule1",
    },
  })
]

and then main module config:

output: {
  publicPath: "http://localhost:8080/",
},
plugins: [
  new ModuleFederationPlugin({
    name: "mainApp",
    filename: "remoteEntry.js",
    remotes: {
      app1: "app1@http://localhost:8081/remoteEntry.js"
    }
  })
]

Both modules are deployed on production.

Then I change Component1 from app1 and deploy app1 module.

How to deal with remote modules caching?

UPDATE:

It looks like in my case the browser uses heuristic caching (https://www.rfc-editor.org/rfc/rfc7234#section-4.2.2) for remoteEntry.js since the server doesn't provide explicit expiration times.

Thus, when remoteEntry.js updates, the main application still loads this file from the cache that could be cached for weeks. For chunks, it's not a problem since webpack could be configured to include hash in the file names.

For remoteEntry.js I see 2 options:

  • cache-busting
  • explicitly specify cache control

Do you think it's a way to go?

like image 723
Pavlo Kozlov Avatar asked Dec 29 '20 16:12

Pavlo Kozlov


People also ask

What is remoteEntry?

remoteEntry. js is the module federation way of allowing your app to be loaded from a remote server, not your actual app code.

How does a federation module work?

Module Federation allows loading separately compiled applications at runtime. Also, we can share common dependencies. This also allows sharing common data like information on the current user or global filters.

How does Webpack module federation work?

Introduced in Webpack 5, the Module Federation plugin gives developers a way to create multiple separate builds that form a single application. Any JavaScript application that is bundled with Webpack 5.0 or greater can dynamically load or share code and dependencies with any other at runtime.

What is ModuleFederationPlugin?

The ModuleFederationPlugin allows a build to provide or consume modules with other independent builds at runtime. const { ModuleFederationPlugin } = require('webpack'). container; module.

Does Webpack 5 module Federation work with remote entry?

With Webpack 5 module federation if remote entry is modified, you don't need to redeploy main module/application and the newest version of the module will be loaded when it's requested by the browser.

Why doesn't Webpack-assets-manifest generate a remote entry for remoteentry?

Because webpack-assets-manifest doesn't generate an entry for remoteEntry.js (a file used by Module Federation to bootstrap remotes), we will fetch it by name only. Note: remoteEntry.js is considered a local chunk in the remote repository. Next, we're getting all remote chunks and returning the code.

Does module Federation work with JavaScript code?

In addition, module federation does not need to load the main entry point or another entire application. It only needs to load the needed code, i.e. a few kilobytes of code. This approach works with any JavaScript code without redundant packages for shared utilities and components.

What is the use of modulefederationplugin?

ModuleFederationPlugin combines ContainerPlugin and ContainerReferencePlugin. It should be possible to expose and use any module type that webpack supports. Chunk loading should load everything needed in parallel (web: single round-trip to server). Overriding modules is a one-directional operation.


1 Answers

Cache busting implies to re-build (or, at least, post-process) the main app bundle, and that is one of the problem module federation tries to avoid.

So, considering remoteEntry.js is usually a small file, the best solution is to apply a specific cache control for this file so it never gets cached.

With nginx, it can be done that way:

location ~ .*remoteEntry.js$ {
    expires -1;
    add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
}
like image 163
ebrehault Avatar answered Oct 27 '22 09:10

ebrehault