重写覆盖node_modules中的依赖文件 打补丁

为什么用?

  有时候使用npm上的包,发现有bug,我们知道如何修改,但是别人可能一时半会没法更新,或者是我们特殊需求,别人不愿意修改,

这时候我们只能自己动手丰衣足食。那么我们应该如何修改别人的源码呢?首先,直接修改node_modules里面的文件是不太行的,

重新安装依赖就没有了。

 通过修复文件的方式对依赖包里的代码进行修复,甚至补充或定制符合自身项目需求的功能.

如何实施?

  1. 在项目更目录创建 rewrite_node_modules 文件夹,与 node_modules 同级,
  2. 在 package.json 文件中的 scripts 中加入 patchFiles 命令,并将此命令配置在各个执行命令之前

    举例: 

    "scripts": {
        "dev": "npm run patchFiles && node --max_old_space_size=4096 node_modules/@vue/cli-service/bin/vue-cli-service.js serve",
        "stage": "npm run patchFiles && node --max_old_space_size=4096 node_modules/@vue/cli-service/bin/vue-cli-service.js --mode stage",
        "build": "npm run patchFiles && node --max_old_space_size=4096 node_modules/@vue/cli-service/bin/vue-cli-service.js build",
        "build:report": "vue-cli-service build --report",
        "build:stage": "npm run patchFiles && node --max_old_space_size=4096 node_modules/@vue/cli-service/bin/vue-cli-service.js build --mode stage",
        "build:preview": "npm run patchFiles && node --max_old_space_size=4096 node_modules/@vue/cli-service/bin/vue-cli-service.js build --mode preview",
        "preview": "serve -s dist",
        "lint": "vue-cli-service lint",
        "postinstall": "npx patch-package",
        "patchFiles": "node ./src/utils/patchFiles.js"
    },

  3.添加文件

./src/utils/patchFiles.js
const fs = require('fs')

const path = require('path')
const chalk = require('chalk')

// 解决 node_modules 修改源码,导致重新装包而要手动替换源码的重复操作。
// 将 new_node_modules 内的文件 覆盖 真正的 node_modules

const REAL_NODE_MODULES = path.resolve('./node_modules') // 旧node_modules

const MY_NODE_MODULES = path.resolve('new_node_modules') // 新node_modules

copy(MY_NODE_MODULES, REAL_NODE_MODULES)

/**

*复制目录中的所有文件包括子目录
*@param{string}需要复制的目录、文件
*@param{string}复制到指定的目录、文件
*@param{function}每次复制前,都会经过一次filterFn,若返回true,则复制。

*/

function copy(origin, target, filterFn = () => true) {
  if (fs.statSync(origin).isDirectory()) {
    // 来源是个文件夹,那目标也整一个文件夹

    if (!fs.existsSync(target)) {
      fs.mkdirSync(target)
    }

    fs.readdirSync(origin).forEach(originName => {
      const originFilePath = path.resolve(origin, originName)

      const targetFilePath = path.resolve(target, originName)

      copy(originFilePath, targetFilePath, filterFn)
    })
  } else if (filterFn(origin, target)) {
    console.info(chalk.blue('已被覆盖的文件:', target))
    fs.copyFileSync(origin, target)
  }
}

console.info(chalk.bold.yellow('💡💡💡 以上的文件已被rewrite_node_modules中的文件替换,升级版本后请注意检查!!!'))

有什么特性?

  1. 同名文件会替换,如果new_node_modules中有而node_modules中没有的文件为新增。
  2. 同名文件的替换是整个文件的复制替换,不是文件内代码的局部替换。
推荐参考:https://blog.csdn.net/xxitcef/article/details/117378817

方案二:

使用patch-package修改Node.js依赖包内容

 

 

方案三:

利用 webpack alias 来覆盖别人代码。

webpack alias一般用来配置路径别名,使我们可以少写路径代码:


chainWebpack: config => {
    config.resolve.alias
      .set('@', resolve('src'))
      .set('#', resolve('src/views/page1'))
      .set('&', resolve('src/views/page2'));
},

思路: webpack alias会替换我们写的“简写路径”,并且它对node_modules里面的文件也是生效的。这时候我们可以将别人源码里面引用模块的路径替换成我们自己的文件。


具体操作如下:

  1. 找到别人源码里面的需要修改的模块,复制代码到src目录
  2. 修改其中的bug,注意里面引用其他的文件都需要写成绝对路径
  3. 找到这个模块被引入的路径(我们需要拦截的路径
  4. 配置webpack alias

 

将   ./patchers 路径替换为 'src/assets/patchers.js'


const path = require('path');
module.exports = {
  chainWebpack: config => {
    config.resolve.alias
      .set('./patchers', path.resolve(__dirname, 'src/assets/patchers.js'))
  }
};

 



posted @ 2022-05-18 09:55  混名汪小星  阅读(1173)  评论(0编辑  收藏  举报