重写 require 函数

Override the require function

本文关键字:函数 require 重写      更新时间:2023-09-26

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

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

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

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

mock-require 通过覆盖 Module._load 来做到这一点(这是真正的require实际上所说的)。

这是一个更安全的本机 ES6 答案,基于 @orourkedd 在所有需求调用上充当事件侦听器,它可能看起来像它的替换 require,但如果你仔细观察,它实际上是在说: require = require并捕获对它的调用,但返回原始行为。这只是数百万次使用Proxy()之一,这对我来说非常方便,例如在 Typescript 中用于将 tsconfig"路径"与实际模块节点映射将解决。

我甚至可以说这不是"猴子补丁",因为它在语言的较低级别。

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

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

我创建了一个名为 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函数。