Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用网页包代码拆分处理部署?_Javascript_Reactjs_Deployment_Webpack_Code Splitting - Fatal编程技术网

Javascript 如何使用网页包代码拆分处理部署?

Javascript 如何使用网页包代码拆分处理部署?,javascript,reactjs,deployment,webpack,code-splitting,Javascript,Reactjs,Deployment,Webpack,Code Splitting,我在野外使用Web包代码拆分时遇到了一个意想不到的问题:想象一下这个场景: 用户加载带有网页包代码拆分的React应用程序,并加载一些捆绑块 部署发生时,用户可能从服务器接收到的任何未来区块的内容都会更新(注意:部署期间,服务器上先前的区块会被删除) 用户单击一个链接并加载一个新的路由,该路由会触发更多要加载的包块。除此之外,这些新块与用户浏览器已加载的块不兼容,并且由于运行时错误,应用程序中断 如何防止这种情况 一个可能的解决方案是维护多个版本的块集,但我想知道是否有一个更简单的解决方案被大规

我在野外使用Web包代码拆分时遇到了一个意想不到的问题:想象一下这个场景:

  • 用户加载带有网页包代码拆分的React应用程序,并加载一些捆绑块
  • 部署发生时,用户可能从服务器接收到的任何未来区块的内容都会更新(注意:部署期间,服务器上先前的区块会被删除)
  • 用户单击一个链接并加载一个新的路由,该路由会触发更多要加载的包块。除此之外,这些新块与用户浏览器已加载的块不兼容,并且由于运行时错误,应用程序中断
  • 如何防止这种情况

    一个可能的解决方案是维护多个版本的块集,但我想知道是否有一个更简单的解决方案被大规模应用程序使用


    如果使用,所有区块都可以预取,但它们只能在短时间内(在Chrome中为5分钟)保持缓存。

    如果区块文件名是散列的,旧路由是否会链接到旧散列区块(可能仍然可用)并加载所有内容?

    确保浏览器拾取已更改文件的简单方法是使用output.filename替换。[hash]替换可用于在文件名中包含特定于生成的哈希,但是使用[chunkhash]替换更好,它在文件名中包含特定于块的哈希。

    作为Max Stoiber:

    服务人员在进行代码拆分时非常方便


    我们使用@nekr提供的优秀离线插件在本地缓存所有当前包,因此无论服务器是否更新文件,ServiceWorker都将始终从本地缓存提供文件。每小时它都会检查服务器是否有更新,如果有更新,则从远程服务器下载所有新捆绑包并在本地缓存。下次用户重新启动应用程序时,将使用新版本的应用程序 这个问题说得非常清楚

    我要补充的是,根据设置,“删除”可能不是正确的名称

    我对这个问题的最初反应是这是一个缓存问题。旧的块文件正在被拾取,而不是新的块文件。这与正在发生的事情很接近,至少在我的案例中,我有以下几点:

    index.js

    const Page1 = lazy(() => import('./page/Page1'));
    const Page2 = lazy(() => import('./page/Page2'));
    
    const main = () => {
      {
        '/page1': Page1,
        '/page2': Page2,
      }[window.location.href](); /* Some Render Router Implementation */
    };
    
  • V1部署在(https://my-domain/distribution_folder/*)
  • 用户将加载V1
    index.js
  • V2部署在(https://my-domain/distribution_folder/*)
  • 用户(尚未刷新)将使用缓存的V1
    index.js
    文件动态加载分块路由
  • 请求将发送到(https://my-domain/distribution_folder/{page_name}.{chunk_hash}.js)
  • 将发生块错误,因为该唯一块将不再存在
  • 这很有趣,因为正在使用的提供者正在将流量迁移到新版本。所以我认为这将是它的结束,但我没有意识到的是,任何用户仍然可以使用以前部署的版本-他们怎么知道?他们已经在使用这个应用程序了。浏览器已下载应用程序(
    index.js

    解决方案实际上取决于动态导入这些块的位置。在上面的例子中,因为它们是页面路由,所以当用户在找不到块的情况下请求不同的页面时,我们可以进行硬刷新。但是,这假设您的
    缓存控制
    头设置正确。例如:

    • index.js
      ->
      缓存控制:无存储
    • page/{page\u name}.{chunk\u hash}.js
      ->
      Cache Control:public,max age=31536000,不可变
    我们可以使这些块不可变,因为有时它们在发布之间不会更改,如果它们不更改,为什么不使用缓存版本。但是,
    index.js
    不能存储在缓存中,因为这是动态加载内容的“路由器”,并且它将始终更改

    专业人士

    • 不再有块加载错误
    • 我们不需要在第一页加载时加载所有内容
    • 通过不使用服务人员来降低复杂性
    缺点

    • 这种方法强制用户刷新
    相关问题


    但在这种情况下,部署将删除旧的散列块,使其不再可用。您可以通过将它们托管在cdn/中来保留旧块。如果它们被散列并上载到同一地点,是的,这是一种完全有效的方法。只要这些文件是真正不可变的:),但在这种情况下,部署将删除旧的散列块,使它们不再可用。我的考虑事项与您的相同。你找到解决办法了吗?谢谢大家!@JordanEnev我们最终维护了部署的多个版本,以便旧的块不会失效。谢谢!如果我找到更简单的,我会写。有兴趣解决这个问题。是否有可能让webpack loader代码响应某种警报,要求用户重新加载?这只是一个简单的解决方案,我们可以在部署后通过websocket使用push,并显示页面应重新加载的通知
    window.navigation.reload()
    ,或者使用长轮询并从某处检查最新版本,例如,从最新的
    index.html
    来看,我不同意这是一个解决方案。最好说“这是解决问题的一个办法”。我不明白开发人员为什么隐藏这些问题。是的,我同意,但我还没有找到更好的解决方案。添加一个服务器工作者会让事情复杂很多。我不会说这是一个变通的方法。这个问题是因为用户需要加载更少的内容——通过这样做,我们需要确保更新不会破坏不使用的用户