在 React Native 中为第三方依赖打补丁

本文由 AI 协助更新

依赖需要本地修改的常见原因包括:上游未合入、发布节奏不匹配,或需要临时修复兼容性。若直接修改 node_modules 下的文件,在下次执行 yarn installyarn add 时会被覆盖,修改随之丢失。

使用 patch-packageopen in new window 可将对 node_modules 的修改固化为补丁文件,在每次安装依赖后通过 postinstall 钩子自动应用,从而持久化这些修改。该方式适合小范围、临时或无法 fork 时的修改;若需长期、大范围改动,可考虑 fork 该依赖或更换库。

安装与配置

安装依赖:

yarn add patch-package postinstall-postinstall

Yarn 在 yarn installyarn add 之后会执行 postinstall,但在 yarn remove 之后不会。加入 postinstall-postinstallopen in new window 可确保 postinstallyarn remove 后也会执行,从而在任意依赖变更后都能正确应用补丁。

package.json 中配置:

{
  "scripts": {
    "postinstall": "patch-package"
  }
}

补丁文件将生成在项目根目录的 patches/ 下,需纳入版本控制,以便团队与 CI 一致应用。

基本用法

流程如下:

  1. node_modules 中找到目标包,直接修改其源码或配置。
  2. 在项目根目录执行:yarn patch-package <package-name>
  3. patches/ 下会生成 package-name+版本号.patch,记录本次修改。

例如需要关闭某依赖的默认行为、或修复其在当前环境下的兼容性时,在对应文件中完成修改后执行上述命令即可生成补丁。此后每次执行 yarn installyarn add,补丁会自动应用,无需再手动改 node_modules

利用社区提供的 diff

许多问题在 GitHub Issue、PR 或讨论中已有他人分享的修改方案(diff)。可直接采用:在 node_modules 中按 diff 修改对应文件,再执行 yarn patch-package <package-name>,即可把该方案固化为项目内的补丁。

示例:react-native-mmkv@2.12.2 适配 Android 16KB page size

现象与影响:在采用 16KB 页面的 Android 设备(如部分 Android 15+)上,安装或商店校验时报错 libreactnativemmkv.so 不支持 16KB,导致无法安装或上架。

背景:react-native-mmkv 的 v2 面向旧架构,官方已不再维护;v3+ 支持 16KB 但需启用新架构。若暂时无法升级新架构,可通过 patch 在 v2 上启用 16KB 支持。

做法:在 Issue #836open in new window评论open in new window中,@belowfrogopen in new window 给出临时方案:在 CMake 参数中增加 -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON,生成与页面大小无关的 so,以支持 16KB。

  1. 打开 node_modules/react-native-mmkv/android/build.gradle,在 externalNativeBuildcmakearguments 中增加该参数:
// 修改前
arguments "-DANDROID_STL=c++_shared"

// 修改后
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
  1. 保存后执行:
yarn patch-package react-native-mmkv

补丁会写入 patches/,之后每次 yarn install 将自动应用。

注意:采用他人提供的 diff 时,请核对库版本(如 2.12.2)与讨论上下文,避免误用于不兼容的版本。

注意事项与参考

  • 补丁与版本绑定:补丁是针对特定依赖版本生成的。升级该依赖后,若其 API 或文件结构发生变化,补丁可能应用失败,需重新检查或重新生成补丁。
  • 建议:对打过补丁的依赖在 package.json 中做好版本锁定;依赖重大升级后执行一次 yarn install 并跑相关构建与测试,确认补丁仍能正确应用。

参考

上次更新: