前言

相信有过一些前端开发经验的同学都有遇到过使用的npm包有bug,或者npm包只要再修改一点点就能满足自己的需求这样尴尬的情况。如果给包作者提需求,作者一般也不会马上给你修改,这时候就需要使用各种修改npm包源码的骚操作了。

通常有四类做法:

  • 单个文件修改法

    • 拷贝覆盖法
    • 修改引用法
  • 整个项目copy法
    • 直接引用法
    • 发布私包法
  • 外部代码修改法
  • 最优解patch-package大法

先直接讲最优解吧

patch-package是一个用来给其他npm包打补丁的包,实际原理也是在本工程保存一份修改的代码,只不过不是用全量代码的形式保存,而是保存了git diff的结果,节省了代码体积

用法如下:

  • npm i -S patch-package安装patch-package
  • 直接在node_modules下修改需要修改的包源码
  • 执行npx patch-package 包名, patch-package会将当前node_modules下的源码与原始源码进行git diff,并在项目根目录下生成一个patch补丁文件
  • 后续只要执行npx patch-package命令,就会把项目patches目录下的补丁应用到node_modules的对应包中,这个执行时机一般可以设置为postinstall这个勾子
"scripts": {"postinstall": "patch-package"
}

为什么是最优解?
毕竟是专门团队开发的工具,在能实现目的的前提下,该考虑的都帮你考虑好了,比如这个包的版本升级了怎么办,你会发现如果你装的包版本和你之前生成的补丁中记录的版本不一样,npx patch-package会直接报错**ERROR** Failed to apply patch for package xxxx at path,另外使用git diff来记录补丁比起重写一份源码的方法更节省空间,即安全,又便捷。

为什么还需要其他方法?
其他方法存在的原因大部分是因为使用者不知道patch-package的存在,基于自己对代码的理解自创的方法,虽然有这样那样的缺点,但在大部分场景下也是没问题的,由于缺少封装,反而使得方法更能体现node运行机制,对初学的开发者还是有一定帮助的。

单文件修改法

之前用过的方法之一,原理是先找到要修改的npm包的文件,先把这个文件拷贝一份到项目目录下,修改,然后只要想办法让这个文件最终被使用就行了

  • 拷贝覆盖法
    还是用postinstall这个勾子,在这个勾子执行cp 修改过的文件 ./node_modules/包名/原始文件拷贝过去,最终node_modules下的文件就变成了修改后的文件了
    例如:
    想修改lodash中的array方法,array-hack.js是被修改后的js文件,现在想用这个文件替换原始文件,只需在package.json加入
"scripts": {"postinstall": "cp ./array-hack.js ./node_modules/lodash/array.js"
}

即在每次install包后执行用修改后文件覆盖原始文件逻辑

  • 修改引用法
    配置一个webpack alias别名,如'原始文件的引用路径': '修改后文件的引用路径',使得最终修改后的文件被引用
    例如:
    与上面同样的情景,只需在webpack配置中加入
resolve: {alias: {'lodash/array': path.resolve(__dirname, '../array-hack.js'),}},

整个项目copy法

也是有同事用过的方法,将需要修改的包的项目源码整个拷贝下来,进行修改,然后使用

  • 直接引用法
    人家完整源码已经有了,直接用就是了,不用npm包了
  • 发布私库法
    适合一个npm包几个项目在用的场景,可以把修改后的源码发布到私有的npm仓库上,供项目使用,这样多个项目就只需要修改一次源码

外部代码修改法

这个方法就是不直接修改node_modules的源码,而是利用js特性,在执行时,修改这个包的内部属性,达到目的
简单来说就是利用defineProperty、prototype等特性修改包内的类
例如:
近期在项目中发现大量使用的设备判断包xxxuser-agent竟然有bug,部分场景下判断异常
则在代码执行最开始阶段,执行以下代码

const ua = require('xxxuser-agent').default;
Object.defineProperty(ua, 'isMobilePhone', {get() {return ua.isMobile && !ua.isIPad && !ua.isWindows && !ua.isMac;},enumerable: true,configurable: true,
});

总结

尽管这些方法都很骚,但始终无法解决修改源码怕升级的问题,如果该npm包升级,可能会导致原先的修改产生错误,所以用了这些骚方法,最好是把包的版本号写死。
唯有patch-package的方法有版本校验,可以防止包被误升级时无人发现,因此还是优先使用这个方法,其余方法仅

node 升级_那些修改node_modules的骚操作相关推荐

  1. mysql骚操作_关于MySQL的一些骚操作——提升正确性,抠点性能

    概要 回顾以前写的项目,发现在规范的时候,还是可以做点骚操作的. 假使以后还有新的项目用到了MySQL,那么肯定是要实践一番的. 为了准备,创建测试数据表(建表语句中默认使用utf8mb4以及utf8 ...

  2. node 升级_技术周刊( Node.js 12 性能大提升 2019-04-30)

    前端快爆 Node.js 12 发布,该版本带来了巨大的性能提升.V8 升级到 7.4 带来了诸多新特性,比如 Private Class Fields.Array#{flat,flatMap} 等: ...

  3. 锁屏界面提示某些设置已隐藏_息屏还有这些“骚操作”,华为这几个隐藏小功能快用起来...

    现在手机系统更新太快了,有时候根本不知道新手机到底有什么便捷功能! 确实,很多小伙伴换了新手机后,都没怎么对系统深入研究,每当得知的时候就一脸"相见恨晚". 对于经常搞机.喜欢发掘 ...

  4. centos升级内核之后修改内核启动顺序

    寡人最近在修复红帽的系统bug,有些是需要升级内核解决的(具体什么bug需要升级内核解决,还是看官网的信息),原来的系统版本和内核版本是 [root@t0 ~]# cat /etc/redhat-re ...

  5. vite下,修改node_modules源码后,在浏览器源码中看不到改动的内容

    一.背景 vite下,修改node_modules源码后,在浏览器的源代码中看不到改动的内容,查看vite文档后发现了这么一段话: 对此我专门做了几次实验,来验证我的一些想法 二.实验的前置操作 执行 ...

  6. 怎么禁止/开启Ubuntu自动更新升级_豆豆技术派的博客-CSDN博客_ubuntu 自动更新

    怎么禁止/开启Ubuntu自动更新升级_豆豆技术派的博客-CSDN博客_ubuntu 自动更新

  7. git idea 可视化_那些你应该知道的,但是你一定不知道的 Git 骚操作

    Hello 大家好,作为团队中的主程阿粉经常参与很多核心功能的开发,而且很多时候一个需求没做好中间又插入新的紧急的需求或者 bug 修复,每次遇到这种情况,如果两个地方代码不冲突的话还好,可以直接在本 ...

  8. 修改js文件需要重启服务器,关于Node.js中频繁修改代码重启服务器的问题

    我们可以使用一个第三方命名行工具,nodemon 来帮我们解决频繁修改代码重启服务器问题. nodemon 是一个基于 Node.jsNode.js 开发的第三方命令行工具,我们使用的时候需要独立安装 ...

  9. 修改node_modules的包

    为啥要修改 有时候使用npm上的包,发现有bug,我们知道如何修改,但是别人可能一时半会没法更新,或者是我们特殊需求,别人不愿意修改,这时候我们只能自己动手丰衣足食. 那么我们应该如何修改别人的源码呢 ...

最新文章

  1. 如何禁止IIS缓存静态文件(png,js,html等)
  2. 投票系统web服务器,创建一个Web投票系统
  3. (译)如何使用cocos2d制作基于tile地图的游戏教程:第一部分
  4. cdn需要备案吗_车子贴改色膜需要到车管所备案吗?
  5. stack操作 and deque操作
  6. 一篇图像识别的科普文
  7. 【开发者portal在线开发插件系列二】多条上下行消息(messageId的使用)
  8. sysbench 1.0.6 mysql_mysql sysbench 1.0.X
  9. php class setter,设置器 - Setters《 PHP 面向对象 》
  10. ORACLE时间常用函数(字段取年、月、日、季度)
  11. 基于python的在线考试系统-基于Django的在线考试系统
  12. IOCAutofac与ORMEntityFramwork的联系--单例模式
  13. 服务器显示RL011,台达伺服驱动器维修之AL011故障原因和方法
  14. tp框架 文件上传+excel表格导入
  15. 中小企业监控体系构建实战--案例分享(内附传送门)
  16. 吉他入门:吉他音阶训练入门教程(二)
  17. 陶哲轩实分析 附录 A 习题解答
  18. 云计算机到底是啥来的,啥叫云计算(云计算究竟是什么)
  19. 微型摄像头的CDS读出电路原理
  20. 7-2 分解素因子 (10 分)

热门文章

  1. cmd上如何运行php文件,cmd - php文件在命令行可以顺利运行,在浏览器上无法正常运行...
  2. bootstrap下拉框分页_学习使用Bootstrap输入框、导航、分页等常用组件
  3. FastDFS多tracker配置
  4. Android开发笔记(一百三十六)可折叠工具栏布局CollapsingToolbarLayout
  5. 启动的时候闪退_APP突然闪退怎么办?学会这五个妙招比换手机实用,看完望周知...
  6. 工作总结 项目中如何处理重复提交问题
  7. Python: ord()函数
  8. ScrollView
  9. 单片机中去耦电容的使用
  10. git 提交代码的步骤