从@expo/vector-icons迁移

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

中文
复制
Moving away from @expo/vector-icons

如果你用过 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 中没有的图标集,例如 Lucide

    • 生成器创建自己的图标集更方便。

    • 使用 createIconSetFromFontellocreateIconSetFromIcoMoon 时可以对图标名做类型检查

  • 更小的应用包体积

    • 应用可能会在无意中打包全部图标字体,哪怕只用到其中一两个。摆脱 @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-iconsreact-native-vector-icons

  • 确保 expo-font 已安装并正确配置。不要把 node_modules/@react-native-vector-icons/ 的字体路径加到 expo-font config plugin 中,否则会导致构建报错。

  • 检查你的自定义图标(如果有)

    • 仔细核对你在用的自定义字体或图标——尤其是之前依赖 createIconSetFromIcoMoon 或类似辅助工具的情况。

可能遇到的问题

  • 图标字体冲突 如果你的项目或其依赖使用了不同的矢量图标包(比如 @expo/vector-iconsreact-native-vector-icons@react-native-vector-icons/some-font),或者同一包的多个版本,那么在不同包里渲染同一字体的图标时,可能会出现意外行为。例如,同一字体在不同包中渲染,图标可能显示为 ? 或空心方块。为避免这些问题,我们新增了一条 doctor 警告,用于检测 @react-native-vector-icons scope 下的新包与 @expo/vector-iconsreact-native-vector-icons 混用的情况。

  • 使用范围广 目前,EAS Build 上约 60% 的应用都包含 @expo/vector-icons。我们清楚这一改动会影响很多项目,因此提供了 codemod,让迁移尽可能顺畅。此外,我们仍会继续维护 @expo/vector-icons,给用户留出迁移时间。迁移过程中遇到问题,欢迎提 issue 或直接告诉我们!

最后

这一改动需要投入一些精力,但能简化代码库,让构建更可预测,二进制文件也可能更小。这也是让 Expo 成为构建和发布移动应用最佳、最现代方式的又一步。在未来的 Expo SDK 版本中,我们将弃用 @expo/vector-icons,完全依赖社区包。

来源: Expo Blog← 返回首页