web-dev-qa-db-ja.com

require関数をオーバーライドする

globalrequire関数をオーバーライドして、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);
    };
})();

これはおそらく、スクリプトが配置されているスクリプトにのみ影響します。

プロセスレベルでどのように変更できますか?

23
Ionică Bizău
var Module = require('module');
var originalRequire = Module.prototype.require;

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

@orourkeddに基づくはるかに安全なネイティブES6の回答は、すべてのrequire呼び出しでイベントリスナーのように機能します。これは、replaceのrequireのように見えるかもしれませんが、実際に言うと、_require = require_でトラップ呼び出しをトラップしますが、元の動作に戻ります。これは、私にとって本当に便利なProxy()の数百万の使用法の1つにすぎません。たとえば、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)
    }
})
_
6

これは私が見つけた回避策です。より良い解決策があれば、私はそれを見るために開いています。

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関数を呼び出すたびに呼び出す必要があることです。

1
Ionică Bizău