【发布时间】: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