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