一、背景
在移动应用开发中,轮播是一种很常见的效果,我们项目采用的是RN跨平台技术,RN的轮播我们直接使用的是第三方插件:react-native-snap-carousel。不过,当我们在项目中使用的时候却发现Android和iOS的表现不一致:stackoverflow.com/questions/6…。
通过分析发现,react-native-snap-carousel的源码有对android和iOS进行分开处理,那怎么办呢?首先我们想到的是将源码拉取下来,使用源码依赖,不过这种不方面后面的CI/CD,后面通过查找资料发现可以使用npm补丁包的方式来解决这种问题。
二、npm补丁包
安装插件
首先,安装 patch-package:
npm i patch-package --save-dev
创建补丁
直接在项目根目录下的 node_modules 文件夹中找到要修改依赖包的相关文件,然后回到根目录执行如下命令制作补丁文件。
# npm > 5.2
npx patch-package package-name
# yarn
yarn patch-package package-name
package-name 就是要修改的依赖包名。执行完成后,会在项目根目录的 patches 目录中创建补丁文件 package-name+0.44.0.patch(0.44.0 是依赖包版本),这个补丁需要提交到代码仓库中。
以下是创建补丁时的一些可选参数:
-
--use-yarn:patch-package 默认是根据项目中的 lockfile 来决定使用 npm 还是 yarn,如果两种都有,则使用 npm,可以通过这个参数启用 yarn。
-
--exclude :创建补丁文件时,忽略与正则表达式匹配的路径,路径相对于要修改的依赖包的根目录,默认: package\.json$。
-
--include :与 --exclude 相反,创建补丁文件时仅考虑与正则表达式匹配的路径,默认: .*。
-
--case-sensitive-path-filtering:使 --include 或 --exclude 中使用的正则表达式区分大小写。
-
--patch-dir:指定放置补丁文件的目录。
嵌套补丁
支持修改依赖包的依赖包,比如 node_modules/package/node_modules/another-package,通过 / 分隔。
npx patch-package package/another-package
# scoped packages
npx patch-package @my/package/@my/other-package
更新补丁
将制作生成的补丁文件拷贝到根目录下的patches文件夹中。
示例中的补丁包内容如下:
diff --git a/node_modules/react-native-snap-carousel/src/utils/animations.ts b/node_modules/react-native-snap-carousel/src/utils/animations.ts
index bf1c50f..a438f1a 100644
--- a/node_modules/react-native-snap-carousel/src/utils/animations.ts
+++ b/node_modules/react-native-snap-carousel/src/utils/animations.ts
@@ -1,7 +1,7 @@
import { Platform, Animated } from 'react-native';
import type { CarouselProps } from 'src/carousel/types';
-const IS_ANDROID = Platform.OS === 'android';
+const IS_ANDROID = false;
// Get scroll interpolator's input range from an array of slide indexes
// Indexes are relative to the current active slide (index 0)
添加指令
在 package.json 的 scripts 中加入 "postinstall": "patch-package",后续执行 npm install 或 yarn install 命令时,会自动为依赖包打补丁了。
"scripts": {
"postinstall": "patch-package"
}
查看结果
再次运行项目,然后打开node_modules下的文件,会发现代码已经替换成了补丁包的内容。
使用patch-package实现npm补丁包时有两点需要注意:
-
要修改的依赖包版本最好是固定的,即不会自动升级版本,这样可以避免自动升级后导致补丁包失效,从而打包失败影响原有功能;
-
协同开发的同学需要重新安装一下依赖;