从@expo/vector-icons迁移
我们将复现应用的包体积通过从@expo/vector-icons切换到@react-native-vector-icons减少了4 MB。以下是我们现在推荐这一更改的原因。
中文
复制

如果你用过 Expo,多半也依赖过 @expo/vector-icons。是时候向前看了。
我们建议从 @expo/vector-icons 迁移到更好的替代方案:各图标包专用的 @react-native-vector-icons 包 的最新版本,它们完整支持 Expo 应用,包括 Expo Go。这一改动简化了生态、减少了困惑,还能缩小应用的打包体积。下面我们说明为什么给出这个建议、它对你们的应用意味着什么,以及如何平滑迁移。
为什么 @expo/vector-icons 不再是推荐方案
历史背景
最初创建 @expo/vector-icons 时,我们把它做成 react-native-vector-icons 之上的一层便利封装,专为与 Expo 项目无缝配合而设计。它用 expo-font 动态加载图标字体,因此即使在字体没有原生打包的情况下,开发构建、OTA 更新和 Expo Go 中也能正常工作。但自 @expo/vector-icons 诞生以来,Expo 已经发生了巨大的变化。
别名带来的复杂度
为了支持那些导入并使用 react-native-vector-icons 的第三方库,我们用 Babel(现在是 Metro)把它别名到 @expo/vector-icons。这带来了不必要的复杂度和维护负担。
不属于 Expo 的核心职责
维护一个封装第三方图标字体的包,与 Expo 专注平台级能力的定位并不一致。我们希望赋能生态,而不是重复造轮子。
更好的做法:直接使用 @react-native-vector-icons 的包
@react-native-vector-icons 中各包的最新版本(不要与已废弃的 react-native-vector-icons 包 混淆)现在直接与 expo-font 集成,并在需要时调用其原生字体加载 API。
这些新包在所有重要场景下都能工作——Expo Go、开发构建,以及所有平台。因此,封装层已无必要,我们将在未来的 Expo SDK 版本中废弃 @expo/vector-icons。
迁移的好处
-
新特性
-
更小的应用包体积
- 应用可能会在无意中打包全部图标字体,哪怕只用到其中一两个。摆脱
@expo/vector-icons有助于减少这种冗余。在我们的复现应用中,仅仅改了一行 import 语句和 package.json 里的一个依赖,发布包和资源体积就减少了约 4 MB。
- 应用可能会在无意中打包全部图标字体,哪怕只用到其中一两个。摆脱
-
更干净的项目配置
-
不再需要别名配置
-
图标包只有一个来源
-
版本漂移或意外行为的风险更低
-
如何迁移你的应用
我们写了一个 codemod,可以自动把 @expo/vector-icons 的 import 更新为 @react-native-vector-icons:
-
在项目中运行
npx @react-native-vector-icons/codemod,检查输出结果。 -
运行
npx expo doctor,确认项目中不再残留@expo/vector-icons或react-native-vector-icons。 -
确保
expo-font已安装并正确配置。不要把node_modules/@react-native-vector-icons/的字体路径加到expo-fontconfig plugin 中,否则会导致构建报错。 -
检查你的自定义图标(如果有)
- 仔细核对你在用的自定义字体或图标——尤其是之前依赖
createIconSetFromIcoMoon或类似辅助工具的情况。
- 仔细核对你在用的自定义字体或图标——尤其是之前依赖
可能遇到的问题
-
图标字体冲突 如果你的项目或其依赖使用了不同的矢量图标包(比如
@expo/vector-icons、react-native-vector-icons和@react-native-vector-icons/some-font),或者同一包的多个版本,那么在不同包里渲染同一字体的图标时,可能会出现意外行为。例如,同一字体在不同包中渲染,图标可能显示为?或空心方块。为避免这些问题,我们新增了一条 doctor 警告,用于检测@react-native-vector-iconsscope 下的新包与@expo/vector-icons或react-native-vector-icons混用的情况。 -
使用范围广 目前,EAS Build 上约 60% 的应用都包含
@expo/vector-icons。我们清楚这一改动会影响很多项目,因此提供了 codemod,让迁移尽可能顺畅。此外,我们仍会继续维护@expo/vector-icons,给用户留出迁移时间。迁移过程中遇到问题,欢迎提 issue 或直接告诉我们!
最后
这一改动需要投入一些精力,但能简化代码库,让构建更可预测,二进制文件也可能更小。这也是让 Expo 成为构建和发布移动应用最佳、最现代方式的又一步。在未来的 Expo SDK 版本中,我们将弃用 @expo/vector-icons,完全依赖社区包。