【问题标题】:Angular ng-upgrade stuck in infinite loop with singleton providerAngular ng-upgrade 与单例提供程序陷入无限循环
【发布时间】:2022-01-20 07:09:58
【问题描述】:

我们正在为一个拥有庞大而混乱的代码库(794k+ JS LoC,396k+ JSP LoC)的大客户执行 AngularJS-Angular 迁移,并且遇到了我们正在努力解决的问题。这是一个人为的问题,所以我将尝试解释一下上下文。

直到最近,他们还有几十个不同的手动复制版本的 AngularJS,都是 1.5.6 或更低版本。我们设法将它们放到一个 NPM 管理的 AngularJS 1.8.2 副本上。然而,一些重大更改是如此之大,以至于我们觉得我们无法在任何地方修复它们 - 例如,$http 重大更改影响了该代码库中成千上万的地方。

因此,我们所做的是将 HTTP 服务(以及其他一些服务)从 1.5.6 反向移植到 1.8.2。我们使用.provider(...) 函数将旧提供程序的副本传递给新版本的AngularJS。我们只在我们向后移植的服务中没有已知的安全修复程序时这样做。这解决了这个问题,但后来我们遇到了另一个问题:像 HTTP 提供者这样的一些提供者有状态。当提供者被多次使用时,这种状态可能会丢失——AngularJS 使用new 从我们的构造函数中实例化提供者,此时 HTTP 提供者的任何先前状态都将被清除。在客户端的应用程序中存在很多复杂的误导,因此同一个提供者很可能在同一个会话中被反向移植两次。因此,我们遇到了一个问题:提供程序被构造了两次,并且在第二次构造中清除了在第二次构造之前可能已更改的 HTTP 提供程序的状态。

所以,为了避免这种情况发生(我感觉有点像是在忏悔箱里……)我们添加了一层抽象来将其变成单例:

let innerHttpProviderInstance = null;
function $HttpProvider_V_1_5_6() {
  if(innerHttpProviderInstance == null) {
    innerHttpProviderInstance = new $HttpProvider_V_1_5_6_inner();
  }
  return innerHttpProviderInstance;
}

//The original HttpProvider from 1.5.6
function $HttpProvider_V_1_5_6_inner() { ... }

然后这样使用(在许多地方):

const app = angular.module('app', mainAppDependencies).config(['$provide', '$controllerProvider','$locationProvider', function($provide, $controllerProvider,$locationProvider) {
    ...
}])
  .provider('$http', $HttpProvider_V_1_5_6)

现在,我们终于接近完成对 AngularJS 1.8.2 的升级,并且正在考虑使用 ng-upgrade 迁移到 Angular。我们有一个非常简洁的混合架构设置:Angular 应用程序upgrades 是根 AngularJS 节点,而 downgrades 是 Angular 叶节点。我们希望首先升级几个 neaf 节点,然后一次升级这些节点的一个父节点,直到我们在 Angular 上拥有整个分支。这主要基于 Victor Savkin 的“升级 Angular 应用程序”。在引入上述单例更改之前,这似乎运作良好。现在,每当应用程序加载时,它都会陷入无限循环,重新加载页面并将!#%2F 添加到 URL 的开头。这似乎类似于以下 GitHub 问题,但显然已修复:https://github.com/angular/angular/issues/5271

当我们从提供者反向端口中删除单例时,它可以正常工作。当我们以任何方式重新引入它时(我们已经尝试了许多方法),它又会崩溃。我认为它与绑定有关,并且 ng-upgrade 试图重新加载页面,因为它认为状态已经改变,但我真的不清楚。所以,这就是我们发现自己所在的 gundarks 的巢穴。对我们接下来的步骤有什么建议吗?

编辑:我们碰巧偶然发现了setuplocationsync,这似乎与这里发生的事情有关。如果我理解正确,它应该解决一个已知的错误,其中 Angular/AngularJS 触发彼此的路由,导致它们循环。当我们在设置中调用这个函数时,它几乎解决了这个问题——页面最终会加载(而在它无限期地重新加载之前),但它仍然会经历几十次重新加载迭代,而不仅仅是将!#%2F 添加到 URL 它现在重复完整的 URL 像这样(我们试图到达页面 /full-url/):/full-url/full-url/full-url/full-url/.../full-url?params=vals

【问题讨论】:

    标签: javascript angular angularjs ng-upgrade


    【解决方案1】:

    我可能无法准确回答为什么它会循环,但这里是我在迁移可能有用的应用程序时采取的步骤。我们也没有升级任何 angularjs 服务/组件,只是降级了迁移的 Angular。

    订单去了: 常量>服务>对话框>组件>路由

    在整个迁移过程中创建接口和清理确实从未停止过,但在后期阶段使用接口会有所帮助。如果还没有,我建议先完成它。我还建议创建一个端点常量来存储你所有的 http 内容。

    对于服务,我们是从叶子开始的。我们的大多数应用程序都有 $http 连接分散在整个应用程序中,因此在将所有内容转移到端点常量和创建单个 http 服务之间,使调试变得更加容易。我建议从注入最少的小型服务开始,然后逐步迁移所有内容。

    将所有内容迁移到单个服务和常量后,如果循环问题仍然存在,您应该能够更轻松地诊断循环问题,或者完全移至 HTTPClient 并查看是否停止循环。

    如果循环是一个直接的问题,从挑选出 http 服务开始,然后处理端点常量

    对话框和组件是比较乏味的工作,将是不同的讨论。

    我会在下面留下一些资源。

    资源: 查看代码工艺,他们有很棒的课程 ng-migration 也是统计和跟踪的好工具

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 2021-12-31
      • 2021-12-13
      • 2020-05-13
      相关资源
      最近更新 更多