覆盖require函数

时间:2015-01-14 16:53:44

标签: javascript node.js require

是否可以覆盖全局 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);
    };
})();

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

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

4 个答案:

答案 0 :(得分:54)

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

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

答案 1 :(得分:8)

答案 2 :(得分:4)

这是一个基于@orourkedd的更安全的原生ES6答案,它在所有需要调用时就像一个事件监听器。它可能看起来像它的替换需要但是如果你仔细观察它实际说:require = require和陷阱调用它,但返回原始行为。这只是Proxy()数百万次使用中的一种,这对我来说非常方便,例如在Typescript中用于映射tsconfig“paths”,真实模块节点将解析。

我甚至会说这不是“猴子修补”,因为它在语言的较低层次上。

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)
    }
})

答案 3 :(得分:1)

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

我创建了一个名为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功能都必须调用。