Webpack使用applyPluginsAsyncSeriesBailResult1
方法運行解析器的所有插件。這個方法運行連續的所有插件 - 下一個插件僅在當前插件執行完成後才運行。 這裏的bail
表示一旦一個插件返回錯誤,該序列就會中斷。這種方法也被稱爲「快速失敗」。但是BailResult
意味着只要一個插件返回結果,序列也會中斷。您可以從來源看出來:
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
插件裏面有參數,你中斷序列。第一個參數是錯誤,第二個參數是結果。這符合Node.js
期望的回調簽名。如果您撥打不帶參數的callback
,則序列爲繼續。
現在,您還可以撥打doResolve
,這將再次運行整個插件序列。這通常是在對請求進行一些更改時完成的,因此您希望再次給所有其他插件以對新請求做出反應。由於當前的插件將在下一個doResolve
輪次中再次調用,因此請確保構建它以防止遞歸。的WebPack後衛再次遞歸,但只有當path
,request
,query
directory
和module
比賽作爲可以從源頭上可以看出:
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 "));
而且回調到doResolve
你平時打電話callback()
從本輪插件打破內因爲他們有機會對更新的請求做出反應:
resolver.plugin(this.source, function(request, callback) {
if (something) {
resolver.doResolve(target, obj,
"aliased with mapping '" + name + "': '" + ...,
function() { callback(error, result) }
)