离谱架构系列——我在祖传代码里发现了【智子】

现象

在我们公司的一个维护了20多年的项目里,发现只要引用第三方组件库或者方法库,都会报错。无论是把bootstrap v3换成v5,还是引用vue.js。由此,我意识到这个项目维护了20多年,几乎很少有新的库的引用,一直在用十几年前/20多年前的插件,原因可能就在这里。我还联想到《三体》小说里的智子封锁地球科技的情节,这个bug可能就是让开发者直呼"新技术不存在了"的智子了。

智子锁死的并非是人类的全部科技,智子锁死的人类基础科学是基于以下认知:科学技术的全面发展取决于基础科学的发展,而基础科学的基础又在于对物质深层结构的探索,如果这个领域没有进展,科学技术整体上就不可能产生重大突破。即将锁死基础科学就等于堵塞该星球提升文明等级的道路。

原因分析

看报错信息,都是指向了filter方法。看已有的代码,我发现filter似乎和正常的用法不一样。

我直接在浏览器上输入了[].filter,发现打印出来的不是【native code】,而是这样的:

点击可以进入filter所在的代码:

至此:我们找到问题点了:由于项目年代十分久远,在数组的filter等方法出来之前,有人在网上找了一些方法,是数组方法的扩展,其中包括了filter,并且将其写到数组的prototype上。

js 复制代码
var extendArr = {
    filter: function(f, g) {
        var e = g || window;
        var b = [];
        for (var d = 0, c = this.length; d < c; ++d) {
            if (!f.call(e, d, this[d], this)) {
                continue
            }
            b.push(this[d])
        }
        return b
    },
	// 还有很多其他的数组方法,不一一列举了
};
for (var method in extendArr) {
    Array.prototype[method] = extendArr[method]
}

if (!f.call(e, d, this[d], this))这一行看,我们发现d是在this[d]前面,也就是说,这个filter方法的value和index是颠倒的。

运行效果:

js 复制代码
var arr = ['a', 'b']

arr.filter(v => v == 'a')
// 运行结果是 []

arr.filter((i, v) => v == 'a')
// 运行结果是 ['a']

下图是bootstrap v5的打包文件,在我们的环境下,572行执行的时候直接报错。

后果

正如《三体》中的智子干扰物理实验,使得地球的科技停滞不前一样,这一段代码让我们这个庞大的项目永远无法引用新技术。

在我们这个项目的环境下,关于filter的代码全部都是有问题的。因此我们想引用第三方组件库,只要源码里用到了filter方法,全部无法正常使用。(这里列举出来的只有filter方法,实际上,some、every这样的方法都被魔改过)。

动弹不得的现状

初步搜索后,发现有几百个地方用到了filter方法,甚至一些关联的公共组件库也用到了。如果删掉这段代码,会导致我们的系统瘫痪。

最终我们只能走两条路:

  1. 在现有的架构上继续开发,放弃第三方组件库;
  2. 对于新的页面,我们放弃通用的架构,jqGrid等插件都不引用;

第一种方式,就是【闭门造车】,第二种情况,要求员工走出舒适区,不再Ctrl CV已有的代码。

启示与思考

  1. 避免出现破坏底层的改动,否则后续产生的技术债难以想象。

另一个离谱的架构设计是这样的:UI提供了三个字体文件,分别是font-bold.wofffont-regular.wofffont-thin.woff,这样切换字体的粗细就不是用font-weight了,而是用font-family。结果所有的第三方UI库的加粗功能全部与这个设定冲突。

这也是魔改了最基础的底层逻辑:不再使用font-weight来设置字体粗细。改了这个底层逻辑后,所有依赖font-weight的库都将受到影响。

  1. 公司是否考虑定期的架构维护

很多公司的技术架构,都是非必要不升级的,因为公司都是业务导向的,只要这个功能可以用,并且有客户正在使用,大概率是不会花精力重构的。而新业务的开发,也大概率沿用已有的技术架构。

所以真正的【智子】不仅仅是破坏了底层的代码,而是公司对于技术、对于员工的态度。如果公司认为技术革新不重要,只要这些老项目有员工扛着就万事大吉,那么技术的封锁就已经形成。

相关推荐
Csvn7 小时前
原型链、this 与闭包内存:三座深水区一次打通(含内存泄漏排查实战)
前端·javascript
万维易源8 小时前
趣味项目素材|免费脑筋急转弯查询接口实战接入教程
javascript·免费api·脑筋急转弯查询·脑筋急转弯接口
SLD_Allen10 小时前
Go语言runtime全景
开发语言·javascript·golang
风萧何11 小时前
架构艺术,是权衡的艺术。
前端·javascript·架构
偷偷挖矿的牛马矿工11 小时前
execa NodeJs新一代child_process的强力替代品
javascript
水獭比特12 小时前
工作流都公开了,为什么还不能继承 Owner 权限?
javascript·人工智能·node.js
ly768914 小时前
Vue 3 从入门到工程实践:基础语法、组件化、路由、状态管理与项目部署
前端·javascript·vue.js
四千岁14 小时前
抓包LangChain-了解LangChain的原理
前端·javascript·后端
用户2986985301415 小时前
使用 JavaScript 在 React 中实现 Word 转 PDF
前端·javascript·react.js