core-js常见于qiankun中的多份polyfill冲突问题

文章详细分析了在微前端框架如qiankun中,由于core-js不同版本加载顺序导致的Math对象常量DEG_PER_RAD和RAD_PER_DEG无法重定义的错误。问题源于core-js3.23.0版本后的修改,使得这些常量变为不可配置和不可写。解决方案包括排除相关polyfill,特别是esnext.math.deg-per-rad和esnext.math.rad-per-deg,以及考虑升级所有应用到最新core-js版本。此外,也提供了针对swc的polyfill策略排除方法。
摘要由CSDN通过智能技术生成

问题

开门见山,你可能会在 qiankun 等微前端体系中,有多个子应用时,发生这样的加载崩溃问题:

Cannot redefine property: DEG_PER_RAD

Cannot redefine property: RAD_PER_DEG

实际上 DEG_PER_RADRAD_PER_DEG 都是 Math 上的静态常量,在以下的描述中,我们就以 Math.DEG_PER_RAD 为例进行拆解。

原因拆解

崩溃的根本原因是,core-js3.23.0 做出了一个改动:不能对 Math.DEG_PER_RAD 重复赋值( 相关 issue 详见 #1091 )。

在 core-js 3.23.0Math.DEG_PER_RAD 设定为了 nonConfigurable: truenonWritable: true 的( 代码详见 esnext.math.deg-per-rad.js ),所以当加载了 >= 3.23.0 的 polyfill 后,不能对 Math.DEG_PER_RAD 重新写入了,此时再加载 < 3.23.0 的 polyfill ,就会发生崩溃报错。

而先加载了 < 3.23.0 的 polyfill ,再加载 >= 3.23.0 的话,是没问题的。

为什么常会发生在微前端下?

通过问题拆解,我们发现此报错是与 core-js 不同版本的加载 顺序 强相关的,而在 qiankun 类似的微前端体系下,往往每个子应用都会有一份 polyfill ,所以他们可能会发生本文中的致命冲突,导致应用彻底崩溃。

你可以在全局变量 window['__core-js_shared__'] 中看到当前项目中有多少 core-js 版本:

解法

这里我们先不进一步探究,直接提供解法:

要解的无非是 Math.DEG_PER_RADMath.RAD_PER_DEG 的问题,那我们直接排除这两个 polyfill 就可以了,他们在 core-js 中的名字是 esnext.math.deg-per-radesnext.math.rad-per-deg

如何排除?

对于社区中大部分的脚手架来说,他们的 babel polyfill 策略都是 usage ,所以当你不使用这两个 Math.xxx 常量的时候他是不会引入 polyfill 的。

既然发生了此问题,说明你的 polyfill 大概率是 entry 策略(此处不再展开讲解 babel polyfill 策略),是全量引入的,所以你应该找到相关源头,排除掉他们。

由于排除的手段和 框架 / 脚手架 实现逻辑强相关,所以本文不做具体描述,在排除过程中,除了可以定点排除 esnext.math.deg-per-radesnext.math.rad-per-deg 外,考虑到未来如果新增其他的 Math.constant 常量,也要再排除,同时 esnext.math.xxx 都是 stage 1 的 polyfill (详见 proposal-math-extensions ),几乎不会有人使用到,全部排除了也是没什么风险的,故可以把 esnext.math.xxx 全部过滤掉。

当你无法触及、或不了解框架行为,不能自行解决时,可以考虑到相关框架、脚手架的 issue 区反馈,寻求维护者的帮助。

swc 的 polyfill 策略排除法

为了讲解的更全面,此处我们还提供 swc 的 polyfill 排除解法。对于 swc 来说,我们推荐使用的 polyfill 策略是人工指定 includes 方法(因为 swc 的 usage 策略速度慢,且更新不及时),详见:

那在获取 polyfill 列表结束后,人工过滤掉 esnext.math.xxx 的 polyfill 即可:

// 过滤部分逻辑
const filteredList = (list as string[]).filter(line => {
  // https://github.com/zloirock/core-js/issues/1091
  // Prevent `Math.DEG_PER_RAD` / `Math.RAD_PER_DEG` constant override problem in qiankun micro app
  return !line.startsWith('esnext.math.')
})
其他可能的解法

除了从 core-js 本身上来解决该问题,这里再提供一些其他的解法思路:

  1. 将主应用、子应用全部升级到最新的 core-js 版本,避开含有 < 3.23.0core-js 情况,可解此问题。

  2. 因为主应用含有 polyfill ,子应用没有独立使用的场景时,无需 polyfill ,把子应用的 polyfill 关掉就可以了。

总结

core-js 本身是没问题的,只不过你加载了多份 polyfill ,那就说不准了,这就是:微前端路漫漫其修远兮,只有踩过了坑才知道事出不易。

由于本文探讨的问题场景比较特定和深入,更多的面向对 webpack 比较了解的用户,跳过了很多基础概念的介绍,希望对你有所帮助。

vue-element-admin qiankun是将vue-element-admin框架与qiankun微前端框架相结合的方案。 vue-element-admin是一个基于Vue.js和Element UI的前端框架,它提供了一套完整的后台管理系统解决方案,包括登录、权限管理、数据展示等功能。它使用了Vue的单文件组件的开发方式,使得代码结构清晰,并且提供了丰富的组件和插件,大大加快了开发速度。同时,它还使用了Element UI组件库,样式美观且易于使用。 而qiankun是一个基于微前端架构的开源框架,能够帮助我们将多个独立的前端应用整合到一个统一的页面。它具有独立性、解耦性和可复用性等特点,可以将不同的前端应用打包成独立的子应用,再通过qiankun的主应用进行管理和展示。 将vue-element-admin与qiankun相结合,可以实现在一个页面同时展示多个vue-element-admin的实例。这样做的好处是可以将不同模块的前端开发团队独立进行开发和维护,提高开发效率和代码的复用性,同时能够实现整体页面的动态切换和加载,提升用户体验。在使用过程qiankun提供了一些API和生命周期钩子函数,方便我们进行子应用之间的通信和数据共享。 总之,vue-element-admin qiankun是将两个优秀的前端框架相结合,能够提供更强大的前端开发和管理能力,可以应对更加复杂的项目需求,提升开发效率和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值