557 字
3 分钟
解决 Tabler 升级导致分块过多的 Bug
前两天对项目的依赖做了一次升级,已经两年没有更过了,这次涉及的依赖是 mantine 和 tabler,但升级之后出现了一个神秘问题,本文用于记录现象、排查过程与解决方案。
严格来说,这是 tabler 和 vite 的问题。
问题现象
- 开发环境初始化加载 6000+ chunks
- 本地服务冷启动耗时增加约30秒
- 生产构建不受影响
排查过程
先观察异常请求的特征
通过 Network 面板发现大量 <5kb 的 chunk 请求,点开响应可以看到包含 @tabler 关键字。
从依赖上溯源
在 @tabler/[email protected]
的源码中发现他是通过动态导入的方式加载所有图标的:
var dynamicImports = {
"a-b-2": () => import('./icons/IconAB2.mjs'),
// ...
}
export { dynamicImports as default };
import()
属于动态导入,对于每一个导入的内容,vite 都会创建出一个独立的 chunk,到这里还不能说完全有问题,关键在于他使用 dynamicImports
的地方:
import * as dynamicImports from './dynamic-imports.mjs';
export { dynamicImports };
在 tabler 这个依赖的入口文件 tabler-icons-react.mjs
中,他将 dynamicImports
给直接导入导出了,就意味着你如果导入了 @tabler/icons
,在开发环境下,vite 分析依赖的时就会把相关的的模块全都加载进来。
根据 issue 的记录,这个写法是为了支持动态加载图标而加入的,就是 <Icon name={iconName} />
这种场景,但 pr 提供者似乎完全没有考虑到使用 vite 构建工具的情况。
解决方案
我这里想到、收集到的总共三种:
版本回退
回退到 3.17 版本,这样可能会丢失一些新版本加入的图标
代码修补
通过 patch-package
修改入口文件,把那两行注释掉,失去动态导入的特性。
别名
// vite.config.js
export default {
resolve: {
alias: {
'@tabler/icons-react': 'node_modules/@tabler/icons-react/dist/esm/icons/index.mjs'
}
}
}
跳过依赖的指定入口,直接使用 esm 构建好的静态模块,但这种也要注意一个问题,有些静态文件的名称和导出时的名字不一样,比如 IconBoxSeam
是找不到对应图标的,因为图标文件名是 Package
。
解决 Tabler 升级导致分块过多的 Bug
https://blog.erio.work/posts/解决tabler升级导致分块过多的bug/