使用 patch-package 修改第三方模块

前言

在开发过程中,我们安装的依赖包可能有bug存在,比如性能问题;对依赖包进行优化后重新安装依赖我们的修改就丢失了;针对这个问题: 可以使用 patch-package 修改第三方模块,及时解决第三方依赖包的 bug

安装

npm install patch-package postinstall-postinstall --save-dev

创建补丁

在项目根目录下的 node_modules 文件夹中找到要修改依赖包的相关文件,然后回到根目录执行;

# npm > 5.2
npx patch-package package-name

package-name 是要修改的依赖包名
执行完成后,会在项目根目录的 patches 目录中创建补丁文件 package-name+5.5.1.patch(5.5.1 是依赖包版本),这个补丁需要提交到代码仓库中;

一个简单的例子

我遇到的问题是 React suite 框架中 tree-table 组件大数据量时,开合有性能缺陷,以此为例:

  1. 前期准备

    • 创建一个项目(以 React 为例)
      npx create-react-app demo
      
    • 安装 rsuite 依赖
      cd demo
      npm install rsuite
      npm install patch-package --save-dev
      

    至此,我们得到了一个新的 React 项目,并且安装了 rsuite 依赖;

  2. 修改依赖库代码

    • node_modules\rsuite-table\es\Table.js
      var filterTreeData = function filterTreeData(data, expandedRowKeys, rowKey) {
        var expandedSet = new Set(expandedRowKeys);	// 新增
        return flattenData(data).filter(function (rowData) {
      	if (rowKey) {
      	  var parents = findAllParents(rowData, rowKey);
      
      	  // var _expanded = shouldShowRowByExpanded(expandedRowKeys, parents);
      	  var _expanded = shouldShowRowByExpanded(expandedSet, parents);
      
      	  rowData[EXPANDED_KEY] = _expanded;
      	  rowData[TREE_DEPTH] = parents.length;
      	  return _expanded;
      	}
        });
      };
      
    • node_modules\rsuite-table\es\utils\shouldShowRowByExpanded.d.ts
      // export default function shouldShowRowByExpanded(expandedRowKeys?: RowKeyType[], parentKeys?: RowKeyType[]): boolean;
      export default function shouldShowRowByExpanded(expandedRowKeys?: Set<RowKeyType>, parentKeys?: RowKeyType[]): boolean;
      
    • node_modules\rsuite-table\es\utils\shouldShowRowByExpanded.js
      export default function shouldShowRowByExpanded(expandedRowKeys, parentKeys) {
        if (expandedRowKeys === void 0) {
      	expandedRowKeys = [];
        }
      
        if (parentKeys === void 0) {
      	parentKeys = [];
        }
      
        for (var i = 0; i < ((_parentKeys = parentKeys) === null || _parentKeys === void 0 ? void 0 : _parentKeys.length); i++) {
      	var _parentKeys, _expandedRowKeys;
      
      	// if (((_expandedRowKeys = expandedRowKeys) === null || _expandedRowKeys === void 0 ? void 0 : _expandedRowKeys.indexOf(parentKeys[i])) === -1) {
      	if (!((_expandedRowKeys = expandedRowKeys) !== null && _expandedRowKeys !== void 0 && _expandedRowKeys.has(parentKeys[i]))) {
      	  return false;
      	}
        }
      
        return true;
      }
      
  3. 打补丁

    npx patch-package rsuite-table
    

    得到一个名为 rsuite-table+5.5.1.patch的文件
    demo\patches\rsuite-table+5.5.1.patch

    点击查看rsuite-table+5.5.1.patch
    diff --git a/node_modules/rsuite-table/es/Table.js b/node_modules/rsuite-table/es/Table.js
    index cdfccfa..8f0a194 100644
    --- a/node_modules/rsuite-table/es/Table.js
    +++ b/node_modules/rsuite-table/es/Table.js
    @@ -23,11 +23,12 @@ import { mergeCells, flattenData, isRTL, findRowKeys, findAllParents, shouldShow
      * @returns
      */
     var filterTreeData = function filterTreeData(data, expandedRowKeys, rowKey) {
    +  var expandedSet = new Set(expandedRowKeys);
       return flattenData(data).filter(function (rowData) {
    	 if (rowKey) {
    	   var parents = findAllParents(rowData, rowKey);
    
    -      var _expanded = shouldShowRowByExpanded(expandedRowKeys, parents);
    +      var _expanded = shouldShowRowByExpanded(expandedSet, parents);
    
    	   rowData[EXPANDED_KEY] = _expanded;
    	   rowData[TREE_DEPTH] = parents.length;
    diff --git a/node_modules/rsuite-table/es/utils/shouldShowRowByExpanded.js b/node_modules/rsuite-table/es/utils/shouldShowRowByExpanded.js
    index 47593eb..5cbf6bc 100644
    --- a/node_modules/rsuite-table/es/utils/shouldShowRowByExpanded.js
    +++ b/node_modules/rsuite-table/es/utils/shouldShowRowByExpanded.js
    @@ -6,7 +6,7 @@
      */
     export default function shouldShowRowByExpanded(expandedRowKeys, parentKeys) {
       if (expandedRowKeys === void 0) {
    -    expandedRowKeys = [];
    +    expandedRowKeys = new Set();
       }
    
       if (parentKeys === void 0) {
    @@ -16,7 +16,7 @@ export default function shouldShowRowByExpanded(expandedRowKeys, parentKeys) {
       for (var i = 0; i < ((_parentKeys = parentKeys) === null || _parentKeys === void 0 ? void 0 : _parentKeys.length); i++) {
    	 var _parentKeys, _expandedRowKeys;
    
    -    if (((_expandedRowKeys = expandedRowKeys) === null || _expandedRowKeys === void 0 ? void 0 : _expandedRowKeys.indexOf(parentKeys[i])) === -1) {
    +    if (!((_expandedRowKeys = expandedRowKeys) !== null && _expandedRowKeys !== void 0 && _expandedRowKeys.has(parentKeys[i]))) {
    	   return false;
    	 }
       }
    

部署

package.json 的 scripts 中加入 "postinstall": "patch-package",后续执行 npm installyarn install 命令时,会自动为依赖包打补丁了;

拓展

  1. --reverse
    撤回所有补丁
    Note: 如果打补丁后,补丁文件被修改过,此操作将失败,此时可以重新安装 node_modules
  2. --patch-dir
    指定补丁文件所在目录

参考资料

https://github.com/ds300/patch-package
原文地址: 使用 patch-package 修改第三方模块

posted @ 2022-06-10 16:04  太轻描淡写了  阅读(967)  评论(0编辑  收藏  举报