7

使用 Webpack 5 模块联合,如果远程条目被修改,您不需要重新部署主模块/应用程序,并且当浏览器请求时将加载最新版本的模块。

我想知道:由于远程 URL 保持不变(例如http://localhost:8081/remoteEntry.js),浏览器可能会在每次加载主模块时缓存文件和缓存版本。另一方面,如果您为远程条目添加缓存清除,您将没有缓存。

让我们假设有一个使用 Webpack 5 模块联合的微前端架构的应用程序。有一个远程微前端,其配置如下:

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

然后是主模块配置:

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

这两个模块都部署在生产环境中。

然后我更改Component1app1部署app1模块。

如何处理远程模块缓存?

更新:

在我的情况下,浏览器似乎使用启发式缓存(https://www.rfc-editor.org/rfc/rfc7234#section-4.2.2),remoteEntry.js因为服务器没有提供明确的到期时间。

因此,当remoteEntry.js更新时,主应用程序仍会从可能缓存数周的缓存中加载此文件。对于块,这不是问题,因为 webpack 可以配置为在文件名中包含哈希。

因为remoteEntry.js我看到了 2 个选项:

  • 缓存清除
  • 显式指定缓存控制

你认为这是一条路吗?

4

4 回答 4

4

缓存破坏意味着重新构建(或至少后处理)主应用程序包,这是模块联合试图避免的问题之一。

因此,考虑到remoteEntry.js通常是一个小文件,最好的解决方案是对该文件应用特定的缓存控制,使其永远不会被缓存。

使用 nginx,可以这样做:

location ~ .*remoteEntry.js$ {
    expires -1;
    add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
}
于 2021-07-22T18:04:52.480 回答
0

在我看来,你永远不应该缓存remoteEntry.js,因为那是块映射的地方。(这里的映射是指组件和它们的块 url 之间的映射)。你总是想确保你显示的是最新的远程块。如果映射改变(通常只是意味着远程组件更新),浏览器应该获取新的块。

也就是说,您应该使用缓存破坏块

    output: {
        filename: '[name].[contenthash].js',
    },
    plugins: [
        new container.ModuleFederationPlugin({
            name: "RemoteModule",
            library: { type: "var", name: "RemoteModule" },
            filename: "remoteEntry.js",
            exposes: {
                './SuperButton': "./src/components/SuperButton",
                './SuperButton2': "./src/components/SuperButton2",
            },
            shared: {
                react: { singleton: true, eager: true },
                "react-dom": { singleton: true, eager: true },
            }
        }),
        new HtmlWebpackPlugin({
            template: "./public/index.html"
        })
    ],

在您webpack.config.js推荐的这里https://webpack.js.org/guides/caching/

这样,主机将始终尝试获取remoteEntry.js(没有哈希的固定 url),如果哈希更改,则让浏览器获取新的块 url。

于 2021-08-08T03:39:04.267 回答
0

我参加聚会可能有点晚了,但这是一种解决方案,您可以在构建时在 remoteEntry 末尾附加一个随机字符串。 https://github.com/module-federation/module-federation-examples/issues/566#issue-785273439

于 2021-05-19T13:08:37.243 回答
-1

我不认为这是一个问题,因为 webpack 在构建过程中将缓存清除添加到应用程序的 js 文件中。查看加载应用程序时返回的 HTML 代码,您会注意到加载包的标签在每次部署后都不同。remoteEntry.js是允许从远程服务器加载您的应用程序的模块联合方式,而不是您的实际应用程序代码。

于 2020-12-29T21:40:10.930 回答