pnpm系列之深入解析Patch Dependencies功能,实现依赖补丁

引言:

在日常的开发过程中,经常会遇到需要一些npm包有bug或者功能缺失,第一种方法是我们修改内容后自己发布为新的npm包,第二种就是本文介绍的方式:打补丁。

pnpm作为一款现代化的包管理工具,本身就提供了Patch Dependencies功能,能够帮助我们轻松解决打补丁的问题。

本文将深入探索pnpmPatch Dependencies功能,并给出详细示例,实现对npm包的代码调整。

什么是Patch Dependencies?

Patch Dependenciespnpm的一个强大功能,它允许我们对某个特定的npm包进行修补,而无需修改源代码或升级整个依赖包。通过Patch Dependencies,我们可以在项目中使用自定义的补丁版本,而不影响其他项目。

如何使用Patch Dependencies?

pnpm提供了三个命令来实现Patch Dependencies功能:

  1. pnpm patch <pkg name>@<version>

使用该命令可以为指定的npm包创建一个临时工作区,我们接下来需要在这个目录下进行修改。

示例:

pnpm patch lodash
  1. pnpm patch-commit <patchDir>

patch-commit命令的作用是根据修改过的临时工作区创建补丁,并把补丁保存到项目的patches目录下,以及在package.json中添加pnpm.patchedDependencies设置。

示例:

pnpm patch-commit ./patches/lodash
  1. pnpm patch-remove <pkg...>

patch-remove命令的作用是移除npm包补丁,并恢复到默认状态。

示例:

pnpm patch-remove lodash

实战操作:

假设我们希望对lodash这个npm包应用一个补丁来修改其某个函数的行为。

1. 创建补丁目录

在项目的根目录下执行命令:

pnpm patch lodash

执行成功之后会显示一个临时的目录,我们要新增或者修改的代码就是在这个目录中修改。

比如上图的目录就是:

/private/var/folders/kd/dx6f0j4n73j04x61dlwdvxww0000gn/T/68db26b40666841019d0395d69d5f84a

2. 修改npm包内容

用你喜欢的开发工具打开上一步我们得到的文件夹,找到cloneDeep.js文件,把内部的CLONE_DEEP_FLAG值修改为2。

注意:这个改动没有实际意义,仅仅是演示。

修改后的内容:

var baseClone = require('./_baseClone');

/** Used to compose bitmasks for cloning. */
// 修改前
// var CLONE_DEEP_FLAG = 1,
// 修改后 1->2
var CLONE_DEEP_FLAG = 2,
    CLONE_SYMBOLS_FLAG = 4;

/**
 * This method is like `_.clone` except that it recursively clones `value`.
 *
 * @static
 * @memberOf _
 * @since 1.0.0
 * @category Lang
 * @param {*} value The value to recursively clone.
 * @returns {*} Returns the deep cloned value.
 * @see _.clone
 * @example
 *
 * var objects = [{ 'a': 1 }, { 'b': 2 }];
 *
 * var deep = _.cloneDeep(objects);
 * console.log(deep[0] === objects[0]);
 * // => false
 */
function cloneDeep(value) {
  return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
}

module.exports = cloneDeep;

3. 创建&应用补丁

继续在在终端运行以下命令来应用补丁:

pnpm patch-commit /private/var/folders/kd/dx6f0j4n73j04x61dlwdvxww0000gn/T/68db26b40666841019d0395d69d5f84a

4. 使用补丁版本的lodash

现在我们的项目里的lodash已经经过了改造,我们按照原有方式使用即可。

示例:

const lodash = require('lodash');

var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = lodash.cloneDeep(objects);

以上示例是一个全流程的展示,然而真实的场景往往可能很复杂,有以下几点可以重点关注下:

  • npm包可能需要编译,该怎么做?
  • npm包内某个npm包依赖也要打补丁应该怎么做?

欢迎留言、分享、反馈!

0 条评论