Webpack 插件 - 何时调用 doResolve 以及何时回调?
Webpack plugins - when to call doResolve and when callback?
每个 webpack 解析插件都遵循以下结构:
resolver.plugin(this.source, function(request, callback) {
if (something) {
resolver.doResolve(target, obj, "aliased with mapping '" + name + "': '" + ...)
} else {
callback(...);
}
任何人都可以解释一下我什么时候应该打电话给 doResolve
以及什么时候回调。我在 webpack 文档中找到了这个短语:
To pass the request to other resolving plugins, use the
this.doResolve(types: String|String[], request: Request, callback)
method
但是,我不知道该怎么做。似乎 doResolve
从一开始就开始了这个过程。这是堆栈在 doResolve
:
中的样子
你可以看到阶段是从头开始的。为什么?
Webpack 运行s 使用 applyPluginsAsyncSeriesBailResult1
方法的解析器的所有插件。此方法 运行 继承所有插件 - 下一个插件是 运行 只有在当前插件执行完毕后。
这里的 bail
表示一旦一个插件 returns 出错,序列就会中断。这种方法也称为 "fail-fast"。但是 BailResult
意味着一旦一个插件 returns 出现结果,序列也会被中断。你可以从源码中看到:
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
,序列为continued.
现在,您还可以调用 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) }
)
每个 webpack 解析插件都遵循以下结构:
resolver.plugin(this.source, function(request, callback) {
if (something) {
resolver.doResolve(target, obj, "aliased with mapping '" + name + "': '" + ...)
} else {
callback(...);
}
任何人都可以解释一下我什么时候应该打电话给 doResolve
以及什么时候回调。我在 webpack 文档中找到了这个短语:
To pass the request to other resolving plugins, use the this.doResolve(types: String|String[], request: Request, callback) method
但是,我不知道该怎么做。似乎 doResolve
从一开始就开始了这个过程。这是堆栈在 doResolve
:
你可以看到阶段是从头开始的。为什么?
Webpack 运行s 使用 applyPluginsAsyncSeriesBailResult1
方法的解析器的所有插件。此方法 运行 继承所有插件 - 下一个插件是 运行 只有在当前插件执行完毕后。
这里的 bail
表示一旦一个插件 returns 出错,序列就会中断。这种方法也称为 "fail-fast"。但是 BailResult
意味着一旦一个插件 returns 出现结果,序列也会被中断。你可以从源码中看到:
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
,序列为continued.
现在,您还可以调用 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) }
)