覆盖 require 函数

Override the require function

是否可以覆盖 global require 函数,在 process 级别影响它?

据我所知,require 函数在包装 NodeJS 脚本的函数中作为参数提供:

(function (..., require, __dirname) { // something like this
   // The wrapped code
})(...);

有没有办法修改require功能?

(function () {
    var _require = require;
    require = function () {
        console.log("...");
        _require.apply(this, arguments);
    };
})();

这可能只会影响它所在的​​脚本。

我们如何在进程级别修改它?

这是我找到的解决方法。如果有更好的解决方案,我很乐意看到。

我创建了一个名为 req-modifier.js:

的脚本
module.exports = function (_args) {

    var _require = _args[1];
    function newRequire () {
        console.log("Require is called");
        return _require.apply(this, arguments);
    }          
    newRequire.__proto__ = _require;

    _args[1] = newRequire;
};  

然后从我想修改 require 函数的文件中,我这样做:

require("./req-modifier")(arguments);

var foo = require("./foo");

限制是我每次都必须调用req-modifier函数。

var Module = require('module');
var originalRequire = Module.prototype.require;

Module.prototype.require = function(){
  //do your thing here
  return originalRequire.apply(this, arguments);
};

mock-require does this by overriding Module._load (which is what the real require actually calls).

这是一个更安全的原生 ES6 答案,它基于@orourkedd,它在所有 require 调用中充当事件侦听器,它可能看起来像它的替代 require 但如果你仔细观察它实际上说:require = require 和trap 调用它但 return 原始行为。这只是 Proxy() 的数百万种用途之一,它对我来说真的很方便,例如在 Typescript 中用于映射 tsconfig "paths" 与真实模块节点将解决。

我什至可以说这不是 "Monkey patching" 因为它是较低级别的语言。

var Module = require('module');
Module.prototype.require = new Proxy(Module.prototype.require,{
    apply(target, thisArg, argumentsList){

        let name = argumentsList[0];

        /*do stuff to ANY module here*/

        if(/MyModule/g.test(name)){
            /*do stuff to MY module*/
            name = "resolveAnotherName"
        }

        return Reflect.apply(target, thisArg, argumentsList)
    }
})