Отменить функцию 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);
    };
})();

Это, вероятно, затронет только script, где он находится.

Как мы можем изменить его на уровне процесса?

Ответы

Ответ 1

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

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

Ответ 3

Вот гораздо более безопасный ответ на ES6, основанный на @orourkedd, который действует как прослушиватель событий на всех требуемых вызовах. Может показаться, что его замена требует, но если вы посмотрите ближе, то на самом деле говорите: require = require и ловушки на него но возвращают оригинальное поведение. Это всего лишь одно из миллионов использования Proxy(), которое было действительно удобно для меня, например, в Typescript для сопоставления "путей" tsconfig с реальным модулем node.

Я бы сказал, что это не "исправление обезьяны" как на более низком уровне языка.

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

Ответ 4

Это обходной путь, который я нашел. Если есть какое-то лучшее решение, я открыт для его просмотра.

Я создал script с именем 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.