gpt4 book ai didi

javascript - 如何处理使用代码拆分的 Docker webpack 应用程序的新版本部署?

转载 作者:行者123 更新时间:2023-12-01 15:03:22 25 4
gpt4 key购买 nike

部署我的应用程序的新版本后在 Docker ,

我看到我的 console出现以下错误 打破我的申请 :

Uncaught SyntaxError: Unexpected token '<'

error when webpack chunk is missing

在此屏幕截图中,缺少的源称为: 10.bbfbcd9d.chunk.js ,该文件的内容如下所示:

(this.webpackJsonp=this.webpackJsonp||[]).push([[10],{1062:function(e,t,n){"use strict";var r=n(182);n.d(t,"a",(function(){return r.a}))},1063:function(e,t,n){var ...{source:Z[De],resizeMode:"cover",style:[Y.fixed,{zIndex:-1}]})))}))}}]);
//# sourceMappingURL=10.859374a0.chunk.js.map

发生此错误是因为:
  • 在每个版本中,我们都会构建一个新的 Docker图片 仅限 包括最新版本的 block
  • 一些客户端正在运行 过时的版本和服务器不会有 的决议旧 block 因为 (1)

  • Chunks are .js file that are produced by webpack, see code splitting for more information



    重新加载应用程序会将版本更新到最新版本,但对于所有使用过时版本的用户,它仍然会破坏应用程序。

    我尝试过的一个可能的解决方法是刷新应用程序。如果服务器上缺少请求的 block ,如果请求 .js,我将发送重新加载信号。文件以通配符路径结束。

    Wild card is serving the index.html of the web application, this for delegating routing to client-side routing in case of an user refreshing it's page



    // Handles any requests that don't match the ones above
    app.get('*', (req, res) => {
    // prevent old version to download a missing old chunk and force application reload
    if (req.url.slice(-3) === '.js') {
    return res.send(`window.location.reload(true)`);
    }
    return res.sendFile(join(__dirname, '../web-build/index.html'));
    });

    这似乎是一个糟糕的修复,尤其是在 Android 版 Google Chrome 上,我看到我的应用程序在无限循环中刷新。 (是的,这也是一个丑陋的修复!)

    由于它对我的最终用户来说不是一个可靠的解决方案,因此我正在寻找另一种方法来在用户客户端过时时重新加载应用程序。

    我的 Web 应用程序是使用 webpack 构建的,就好像它是一个 create-react-app应用程序,分布式构建目录包含许多 .js block 文件。

    这些是一些可能的修复 I got offered on webpack issue tracker ,其中一些是由 webpack 创建者自己提供的:
  • 不要删除旧版本。 <= 我正在构建一个 Docker 镜像,所以这有点挑战性
  • 捕获 import()错误并重新加载。您也可以通过修补 __webpack_load_chunk__ 来全局执行此操作某处。 <= 我没有得到那个补丁或在哪里使用 import() ,我不是自己制作这些 block ,它只是一个生产功能
  • 让服务器发送window.location.reload(true)对于不存在的 js 文件,但这是一个非常奇怪的 hack。 <= 它使我的应用程序在 chrome android 上循环重新加载
  • 不要为 .js 发送 HTML请求,即使它们不存在,这只会导致奇怪的错误 <= 那不能解决我的问题

  • 相关问题
  • https://github.com/webpack/webpack/issues/10792
  • https://github.com/webpack/webpack/issues/7502

  • 如何实现可以防止此错误的解决方案?

    最佳答案

    如果我正确理解了这个问题,那么有几种方法可以解决这个问题,我将从最简单的到更复杂的列出它们:

    使用以前的版本来构建新版本

    这是迄今为止最简单的方法,只需要为您的新版本更改基本镜像。

    考虑以下 Dockerfile构建应用程序的版本 2:

    FROM version1

    RUN ...

    然后构建它:
    docker build -t version2 .

    然而,这种方法有一个问题——所有旧 block 都将在更新的图像中累积。它可能是可取的,也可能不是可取的,但要考虑到一些事情。

    另一个问题是您无法轻松更新基础镜像。

    使用多阶段构建

    多阶段构建允许您运行多个阶段并将每个阶段的结果包含到最终图像中。每个阶段可能使用不同的 Docker 镜像和不同的工具,例如GCC 来编译一些 native 库,但最终图像中并不需要 GCC。

    为了使其与多阶段构建一起使用,您需要能够创建第一个图像。让我们考虑以下 Dockerfile正是这样做的:
    FROM alpine

    RUN mkdir -p /app/latest && touch /app/latest/$(cat /proc/sys/kernel/random/uuid).chunk.js

    它使用随机名称的新 block 创建一个新的新 Docker 镜像,并将其放入名为 latest 的目录中- 这对建议的方法很重要!

    为了创建后续版本,我们需要一个 Dockerfile.next看起来像这样:
    FROM version2 AS previous
    RUN rm -rf /app/previous && mv /app/latest/ /app/previous

    FROM alpine

    COPY --from=previous /app /app
    RUN mkdir -p /app/latest && touch /app/latest/$(cat /proc/sys/kernel/random/uuid).chunk.js

    在第一阶段,它通过删除 previous 来轮换版本。版本和移动 latest进入 previous .

    在第二阶段,它会复制第一阶段剩下的所有版本,创建一个新版本并将其放入 latest。 .

    以下是如何使用它:

    docker build -t image:1 -f Dockerfile .

    >> /app/latest/99cfc0e6-3773-40a0-82d4-8c8643cc243b.chunk.js

    docker build -t image:2 --build-arg PREVIOUS_VERSION=1 -f Dockerfile.next .

    >> /app/previous/99cfc0e6-3773-40a0-82d4-8c8643cc243b.chunk.js
    >> /app/latest/2adf34c3-c50c-446b-9e85-29fb32011463.chunk.js

    docker build -t image:3 --build-arg PREVIOUS_VERSION=2 -f Dockerfile.next

    >> /app/previous/2adf34c3-c50c-446b-9e85-29fb32011463.chunk.js
    >> /app/latest/2e1f8aea-36bb-4b9a-ba48-db88c175cd6b.chunk.js

    docker build -t image:4 --build-arg PREVIOUS_VERSION=3 -f Dockerfile.next

    >> /app/previous/2e1f8aea-36bb-4b9a-ba48-db88c175cd6b.chunk.js
    >> /app/latest/851dbbf2-1126-4a44-a734-d5e20ce05d86.chunk.js

    注意 block 是如何从 latest 移动的至 previous .

    此解决方案要求您的服务器能够发现不同目录中的静态文件,但这可能会使本地开发复杂化,认为此逻辑可能是基于环境的条件。

    或者,您可以在容器启动时将所有文件复制到一个目录中。这可以在 ENTRYPOINT 中完成Docker 本身或您的服务器代码中的脚本 - 这完全取决于您,取决于更方便的方式。

    此外,此示例仅查看一个版本,但可以通过更复杂的旋转脚本将其扩展到多个版本。例如,要保留 3 个最新版本,您可以执行以下操作:
    RUN rm -rf /app/version-0; \
    [ -d /app/version-1 ] && mv /app/version-1 /app/version-0; \
    [ -d /app/version-2 ] && mv /app/version-2 /app/version-1; \
    mv /app/latest /app/version-2;

    或者可以使用 Docker 参数化 ARG与要保留的版本数。

    您可以在 official documentation 中阅读有关多阶段构建的更多信息。 .

    关于javascript - 如何处理使用代码拆分的 Docker webpack 应用程序的新版本部署?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61479698/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com