在 React Native 中使用 FontAwesome Free Regular 图标包:安装、动态/静态加载与全平台配置指南

原创2026-09-20 17:22:53813 阅读
文章标签:UI组件移动开发

在 React Native 中使用 FontAwesome Free Regular 图标包:安装、动态/静态加载与全平台配置指南

FontAwesome Free Regular 是 FontAwesome 免费字体中的常规字重图标集合,本仓库中的 @react-native-vector-icons/fontawesome-free-regular 包将其封装为可直接在 React Native 中使用的组件,同时支持完整的样式定制(size、color、style)与图片源(getImageSource)能力。本文以该包的 README.md 为主线,结合仓库源码与各平台设置文档,系统讲解安装、动态/静态两种引入方式、Expo 配置插件、原生平台与 Web 的接入细节,读完即可在 iOS、Android、macOS、Windows 与 Web 上稳定集成这套图标。

一、包是什么:从 FontAwesome 字体到 React Native 组件

@react-native-vector-icons/fontawesome-free-regular 是 react-native-vector-icons 单仓库(monorepo)体系下的一个独立字体包,对应 FontAwesome Free 字体的 Regular(常规)字重,字体文件为 fa-regular-400.ttf。它遵循"一个图标集一个包"的组织方式:每个包自带字体文件、字形映射表(glyphmap)、原生工程接入文件与 Expo 配置插件。

从仓库结构看,该包的核心资产包括:

其中 src/index.ts 与 src/static.ts 都由 packages/generator-react-native-vector-icons 的模板自动生成,两处源码均以 createIconSet 创建图标组件,并导出了类型 FontAwesomeFreeRegularIconName(即 keyof typeof glyphMap,由 JSON 字形映射表推导出的图标名字面量联合类型),使用时可获得完整的 TypeScript 图标名提示。

上游字体版本对应关系

README 中明确指出:12 版本之前,该字体包的版本号与上游 FontAwesome 版本保持一致;12 版本之后改为独立版本号,并提供了版本对照表:

RNVI 包版本 上游 FontAwesome Free 版本
> 0.1.0 7.1.0
> 0.1.1 7.2.0

当前仓库中该包版本为 1.1.2(见 package.json),其 devDependencies 中锁定 @fortawesome/fontawesome-free: 7.2.0,与 README 表格中 > 0.1.1 → 7.2.0 的记录一致,即当前包内置的字体对应 FontAwesome Free 7.2.0。

二、安装:一条命令接入

在 React Native 项目(或 Expo 项目)中执行:

npm install @react-native-vector-icons/fontawesome-free-regular

安装后包内将包含 src、lib、glyphmaps、fonts、android、ios 以及 *.podspec 等发布内容(见 package.json 的 files 字段)。需要注意两个运行时约束:

  • Node 版本:package.json 的 engines 声明 node >= 18.0.0;
  • 依赖关系:运行时仅依赖 @react-native-vector-icons/common(图标组件的公共实现库),而 @expo/config-plugins 是可选的 peerDependency,仅在 Expo 工程中启用配置插件时才需要。

三、两种引入方式:动态加载(默认)与静态加载(/static)

该包提供两个入口,对应两种字体加载策略,README 给出了如下示例:

// 方式一:静态导入(字体随原生构建打包,不进入 JS bundle)
import { FontAwesomeFreeRegular } from '@react-native-vector-icons/fontawesome-free-regular/static';

// 方式二:动态字体加载(默认,字体作为 JS 资源打包,运行时注册)
// 具体说明见 Expo 设置指南
import { FontAwesomeFreeRegular } from '@react-native-vector-icons/fontawesome-free-regular';

// ...

<FontAwesomeFreeRegular name="house" color="#ff0000" size={20} />

两种入口的差异,可以从源码直接看出:

  • src/index.ts 在 createIconSet 的配置中额外传入了 fontSource: require('../fonts/fa-regular-400.ttf'),即把 .ttf 作为 JS 资源打包进 Metro bundle,首次渲染时由 @react-native-vector-icons/common 中的动态加载器(dynamicLoader.loadFontAsync)在运行时注册字体;
  • src/static.ts 不携带 fontSource,字体只通过原生构建(autolinking 复制进原生二进制)到达设备,JS 侧不再重复打包。

动态加载(默认入口):开箱即用、支持 OTA 更新

import { FontAwesomeFreeRegular } from '@react-native-vector-icons/fontawesome-free-regular';

动态加载是 createIconSet 的默认行为。在 packages/common/src/create-icon-set.tsx 中可以看到,当 fontSource 存在且 isDynamicLoadingEnabled() 为真时,组件会在首次渲染时调用 dynamicLoader.loadFontAsync(fontReference, fontSource) 加载字体,加载完成后渲染字形。这种方式无需任何原生配置或配置插件,是唯一兼容 Expo Go 的方案,且字体可通过 OTA 更新。其前提是运行时支持动态加载(Expo SDK >= 52)。

静态加载(/static):为 Development Build 减负

import { FontAwesomeFreeRegular } from '@react-native-vector-icons/fontawesome-free-regular/static';

在 development build 场景下,autolinking 会读取各包的 build.gradle / .podspec 并在构建期把 .ttf 复制进原生二进制。如果此时仍使用动态入口,同一份字体就同时以"原生资源"和"JS 资源"两种形态各打包一次,造成体积浪费。/static 入口跳过 JS 侧 .ttf 引入,让字体只随原生构建分发——这也意味着它不兼容 Expo Go,且内嵌字体无法通过 OTA 替换。若希望保留动态入口又避免重复打包,也可以在 autolinking 中排除该包(详见 docs/SETUP-EXPO.md)。

四、基础用法:组件 Props 与图片源 API

FontAwesomeFreeRegular 本质上是基于 React Native Text 的组件,支持 TextProps 的全部属性。核心 Props 如下:

Prop 类型 说明 默认值
name FontAwesomeFreeRegularIconName 图标名(如 house、bell),来自 glyphmap 映射表 必填
size number 图标字号 来自 DEFAULT_ICON_SIZE(common 包定义)
color TextStyle['color'] 图标颜色 来自 DEFAULT_ICON_COLOR(common 包定义)
style TextStyle 附加样式,与 size/color 合并后覆盖默认样式 无
allowFontScaling boolean 是否跟随系统字体缩放 false
innerRef / ref Ref<Text> 转发到底层 Text 实例 无
import { FontAwesomeFreeRegular } from '@react-native-vector-icons/fontawesome-free-regular';

<View style={{ flexDirection: 'row', gap: 12 }}>
  <FontAwesomeFreeRegular name="bell" size={24} color="#ff0000" />
  <FontAwesomeFreeRegular name="calendar" size={32} color="#4F8EF7" />
</View>

从源码看,组件内部通过 resolveGlyph 把图标名解析为 Unicode 字符,并在样式层设置 fontFamily: fontReference、fontWeight: 'normal'、fontStyle: 'normal' 等覆盖项,确保字形正确渲染。

将图标转换为图片源

createIconSet 创建的组件还附带两个静态方法(见 packages/common/src/create-icon-set.tsx):

FontAwesomeFreeRegular.getImageSource(name, size?, color?)      // 异步,返回 Promise<ImageSource>
FontAwesomeFreeRegular.getImageSourceSync(name, size?, color?) // 同步

它们把字形渲染成图片源,适用于需要在 Image、TabBarIcon 或原生导航栏图标等场景中使用图标的情况,并支持 { size, color } 选项对象的重载形式。动态加载启用时,getImageSource 会先确保字体已加载再生成图片。

五、Expo 配置插件:静态引入时的必配步骤

该包自带 Expo 配置插件(见 app.plugin.js)。如果使用 /static 静态引入,必须把包名加入 app.json 或 app.config.js 的 plugins 数组:

{
  "expo": {
    "plugins": ["@react-native-vector-icons/fontawesome-free-regular"]
  }
}

插件底层使用 @expo/config-plugins 的 withInfoPlist,将 fa-regular-400.ttf 追加到 iOS 的 UIAppFonts(即 Info.plist 的 "Fonts provided by application")中:

const fonts = ['fa-regular-400.ttf'];
c.modResults.UIAppFonts = [...new Set([...(c.modResults.UIAppFonts || []), ...fonts])];

配置完成后运行 npx expo prebuild 重新生成原生工程。需要注意:

  • 该方案依赖原生构建,不适用于 Expo Go,且内嵌字体无法通过 OTA 替换;
  • 不要重复配置:避免把 node_modules/@react-native-vector-icons/... 下的字体再手动添加到 expo-font 配置插件中,以免字体重复注册。

关于动态加载的控制 API(isDynamicLoadingEnabled、isDynamicLoadingSupported、setDynamicLoadingEnabled、setDynamicLoadingErrorCallback),可参阅 docs/SETUP-EXPO.md。

六、原生平台配置:Android / iOS / macOS / Windows

如果你使用纯 React Native(非 Expo),请参考 docs/SETUP-REACT-NATIVE.md。

Android

无需额外配置,重建应用即可。该包在 android/src/main 下提供了 AndroidManifest.xml 与 VectorIconsFontAwesomeFreeRegularPackage.kt(一个空模块的 BaseReactPackage 实现),其作用是让 autolinking 识别并挂载该包、在构建期把字体资源带入应用。字体复制与加载由 autolinking 与 common 包的原生逻辑完成。

iOS

每新增一个字体包,都需要更新 Info.plist:

  1. 运行以下命令,把该包声明的字体写入 ios/AppName/Info.plist:
npx rnvi-update-plist package.json ios/AppName/Info.plist
  1. 打开 ios/Info.plist,确认 Fonts provided by application(文本编辑器中的键名为 UIAppFonts)包含 fa-regular-400.ttf。iOS 侧的资源声明由 react-native-vector-icons-fontawesome-free-regular.podspec 提供(s.resources = 'fonts/*.ttf'),并支持 iOS / tvOS / visionOS 平台。

  2. 在 ios 目录执行 pod install:

cd ios && pod install
  1. 重建应用。

macOS 与 Windows

macOS 仍处于完善阶段(可关注仓库相关 issue);Windows 上需要把 node_modules/react-native-vector-icons/Fonts/* 中的字体复制到 windows/<Project>/Assets/*,在 Visual Studio 中把字体作为 Asset 添加,然后重建工程。

七、Web 接入:@font-face 与 webpack

Web 场景(react-native-web)需要让浏览器感知字体,核心是在 CSS 中声明 @font-face。可参考 docs/SETUP-WEB.md 的做法:

@font-face {
  src: url(path/to/fonts/fa-regular-400.ttf);
  font-family: "FontAwesome7Free-Regular"; /* 需与 postScriptName 对应 */
  font-weight: 400; /* Regular 字重 */
  font-style: normal;
}

如果使用 webpack 等构建工具,需要配置 loader 处理 .ttf:

{
  test: /\.ttf$/,
  loader: "url-loader", // 或 file-loader
  include: path.resolve(__dirname, "node_modules/react-native-vector-icons"),
}

之后便可在入口代码中按常规方式渲染图标。若字体族未生效,可先打开浏览器开发者控制台排查缺失的 font-family(对应源码中的 postScriptName: 'FontAwesome7Free-Regular')。

八、版本管理与升级提示

  • 该包的版本号自 12 起与上游字体版本解耦,升级 FontAwesome 字体时请关注本包的新版本及其 CHANGELOG(见 packages/fontawesome-free-regular/CHANGELOG.md);
  • 包内容由 packages/generator-react-native-vector-icons 的模板生成,若需为仓库贡献对该包的改动,应在生成器模板处修改(src/index.ts、static.ts 顶部注释均有明确说明);
  • 版本对应关系请以本文第一节的表格为准,即当前 1.1.2 对应 FontAwesome Free 7.2.0。

九、贡献与许可

  • 贡献:参见仓库根目录的 CONTRIBUTING.md 了解开发流程与贡献规范;
  • 许可:本包与 react-native-vector-icons 仓库整体均以 MIT 协议发布;使用 FontAwesome 图标时,请同时遵守 FontAwesome Free 的字体许可条款。

综上,@react-native-vector-icons/fontawesome-free-regular 是一个开箱即用的 FontAwesome Free Regular 图标解决方案:日常开发可直接使用默认动态入口,追求包体积优化时切换 /static 入口并配合 Expo 配置插件或原生 plist 配置,即可在移动端与 Web 端获得一致、可完全自定义样式的图标体验。

登录后查看全文
react-native-vector-icons