使用 Webpack 进行新部署后处理丢失的动态块

mad*_*low 5 javascript angularjs angular-ui-router webpack webpack-4

我有一个带有 Webpack (4.x) 的 AngularJs (1.7) SPA。

这是我们创建块名的方式:

  config.output = {
    path: PATHS.build,
    publicPath: '/dist/',
    filename:  `[name]${isDev ? '' : '.[contenthash:8]'}.bundle.js`,
    chunkFilename: `chunks/[name]${isDev ? '' : '.[contenthash:8]'}.chunk.js`
  };
Run Code Online (Sandbox Code Playgroud)

延迟加载是在 ui-router 的状态定义中完成的,基本上是这样的:

  $stateProvider
    .state('reports', {
      url: '/projects/:project_id/reports',
      lazyLoad: function($transition$) {
        const injector = $transition$.injector().get('$injector');
        return import(/* webpackChunkName: "admin.reports.module" */ './reports')
          .then(mod => {
            injector.loadNewModules([mod.default]);
          })
          .catch(err => {
            throw new Error('An error occured, ' + err);
          });
      }
    })
Run Code Online (Sandbox Code Playgroud)

由于对“动态”块中的模块进行更改而进行部署后 - 该块的文件名将更改([contenthash] 已更改)。

当登录用户(在上次部署之前加载所有捆绑资产)现在尝试使用新块打开路由时 - 块不存在(404)并且它将失败:

Transition Rejection($id: 4 type: 6, message: The transition errored, detail: Error: An error occured, Error: Loading chunk 14 failed.
(error: admin.reports.module.8fc31757.chunk.js))
Run Code Online (Sandbox Code Playgroud)

有没有一种通用的方法来规避/处理这个问题?

也许更笼统地说:如何检测捆绑的 Web 应用程序的更改?是否有触发重新加载的常用方法?是否总是需要手动刷新?

小智 6

我认为有几种方法可以规避这个问题,因为当前上下文中的 JavaScript 不知道最新版本生成的内容的新哈希,您可以尝试:

1.) 您可以尝试在散列文件上设置 http 重定向: https: //developer.mozilla.org/en-US/docs/Web/HTTP/Redirections 浏览器将请求旧文件,服务器可以指向新文件而不是返回 404。如果您的所有文件都遵循约定并且一次仅存储一个文件,例如:component.hash.js那么这应该非常简单。

2.) 一种 hacky 客户端方法是在 try catch 中处理转换拒绝并重新加载页面,而无需缓存来获取新资源。https://developer.mozilla.org/en-US/docs/Web/API/Location/reload

总是有不止一种方法,但这就是我能想到的解决问题的方法。