2017-07-26 13 views
3

すべてのWebPACKの解決のプラグインは、以下の構造を、次のとおりです。私はdoResolveとコールバックを呼び出す必要があるときWebpackプラグイン - doResolveを呼び出すタイミングとコールバックを行うタイミング

resolver.plugin(this.source, function(request, callback) { 
    if (something) { 
     resolver.doResolve(target, obj, "aliased with mapping '" + name + "': '" + ...) 
    } else { 
     callback(...); 
    } 

は誰が説明していただけます。私はWebPACKのドキュメントにこのフレーズを見つけた:

this.doResolve使用し、他の解決のプラグインへの要求を渡すには(種類:文字列| String []型、リクエスト:リクエスト、コールバック) 方法を

しかし、私はそれをどうしたらいいのか分かりません。 doResolveが最初からプロセスを開始するようです。ここでは、スタックはdoResolveでどのように見えるかです:

enter image description here

あなたがステージを最初から開始していることがわかります。どうして?

答えて

2

Webpackは、applyPluginsAsyncSeriesBailResult1メソッドを使用してリゾルバ用のすべてのプラグインを実行します。このメソッドは、すべてのプラグインを連続して実行します。次のプラグインは、現在のプラグインの実行が終了した後にのみ実行されます。 bailは、1つのプラグインがエラーを返すとすぐにシーケンスが中断されることを意味します。このアプローチは、「フェイル・ファスト」とも呼ばれます。しかしBailResultは、1つのプラグインが結果を返すとすぐにシーケンスが中断されることを意味します。あなたはソースからそれを見ることができます:

applyPluginsAsyncSeriesBailResult1 = function applyPluginsAsyncSeriesBailResult1(name, param, callback) { 
    var plugins = this._plugins[name]; 
    if(!plugins || plugins.length === 0) return callback(); 
    var i = 0; 
    var _this = this; 
    var innerCallback = function next(err, result) { 
     // if the plugin returned an error or a result - break 
     if(arguments.length > 0) return callback(err, result); 
     i++; 
     // if all plugins have run - break 
     if(i >= plugins.length) { 
      return callback(); 
     } 
     // trigger next plugin - continue 
     plugins[i].call(_this, param, innerCallback); 
    }); 
    plugins[0].call(this, param, innerCallback); 
}; 

ので、このコードから、あなたはできるだけ早くあなたがシーケンス割り込みあなたはパラメータとプラグイン内callbackを呼び出すとことを見ることができます。最初のパラメータはエラー、2番目のパラメータは結果です。これは、Node.jsがコールバックシグネチャをどのように受け取るかに基づいています。パラメーターなしでcallbackを呼び出すと、シーケンスはと続きます。となります。

今や、doResolveを呼び出して、プラグインのシーケンス全体を再度実行することもできます。これは、通常、リクエストにいくつかの変更を適用するときに実行されるので、他のすべてのプラグインに新しいリクエストに再び反応するチャンスを与えたいとします。現在のプラグインが次のdoResolveラウンドで再度呼び出されると、再帰を防ぐようにプラグインを構築してください。 WebPACKのガード再び再帰だけであればpath、ソースから分かるようにrequestquerydirectorymodule試合:

Resolver.prototype.doResolve = function doResolve(type, request, message, callback) { 
    var resolver = this; 
    var stackLine = type + ": (" + request.path + ") " + 
     (request.request || "") + (request.query || "") + 
     (request.directory ? " directory" : "") + 
     (request.module ? " module" : ""); 
    var newStack = [stackLine]; 
    if(callback.stack) { 
     newStack = callback.stack.concat(newStack); 
     if(callback.stack.indexOf(stackLine) >= 0) { 
      // Prevent recursion 
      var recursionError = new Error("Recursion in resolving\nStack:\n " + newStack.join("\n ")); 

そして、あなたは通常、プラグインの現在のラウンドから分割するcallback()を呼び出しdoResolveへのコールバックの内側更新されたリクエストに反応するチャンスがあったためです:

resolver.plugin(this.source, function(request, callback) { 
    if (something) { 
     resolver.doResolve(target, obj, 
       "aliased with mapping '" + name + "': '" + ..., 
       function() { callback(error, result) } 
     ) 
関連する問題