From c0db521c82a3b61be089414610b25ed853d1ed5f Mon Sep 17 00:00:00 2001 From: Greg Venech Date: Wed, 6 Dec 2017 00:19:53 -0500 Subject: [PATCH] docs(api): clarify the `pitch` method and how it can be used in loaders.md Resolves #449 Resolves #116 Refactored and enhanced the existing section using much of @sokra's explanation from: https://github.com/webpack/webpack/issues/360 --- src/content/api/loaders.md | 54 +++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/content/api/loaders.md b/src/content/api/loaders.md index 6914d4ed4fb7..faec84f66b55 100644 --- a/src/content/api/loaders.md +++ b/src/content/api/loaders.md @@ -90,9 +90,31 @@ module.exports.raw = true; ### Pitching Loader -Loaders are **always** called from right to left. But, in some cases, loaders do not care about the results of the previous loader or the resource. They only care about **metadata**. The `pitch` method on the loaders is called from **left to right** before the loaders are called (from right to left). +Loaders are __always__ called from right to left. There are some instances where the loader only cares about the __metadata__ behind a request and can ignore the results of the previous loader. The `pitch` method on loaders is called from __left to right__ before the loaders are actually executed (from right to left). For the following [`use`](/configuration/module#rule-use) configuration: -If a loader delivers a result in the `pitch` method the process turns around and skips the remaining loaders, continuing with the calls to the more left loaders. `data` can be passed between pitch and normal call. +``` js +use: [ + 'a-loader', + 'b-loader', + 'c-loader' +] +``` + +These steps would occur: + +``` diff +|- a-loader `pitch` + |- b-loader `pitch` + |- c-loader `pitch` + |- requested module is picked up as a dependency + |- c-loader normal execution + |- b-loader normal execution +|- a-loader normal execution +``` + +So why might a loader take advantage of the "pitching" phase? + +First, the `data` passed to the `pitch` method is exposed in the execution phase as well under `this.data` and could be useful for capturing and sharing information from earlier in the cycle. ``` js module.exports = function(content) { @@ -100,14 +122,34 @@ module.exports = function(content) { }; module.exports.pitch = function(remainingRequest, precedingRequest, data) { - if(someCondition()) { - // fast exit - return "module.exports = require(" + JSON.stringify("-!" + remainingRequest) + ");"; - } data.value = 42; }; ``` +Second, if a loader delivers a result in the `pitch` method the process turns around and skips the remaining loaders. In our example above, if the `b-loader`s `pitch` method returned something: + +``` js +module.exports = function(content) { + return someSyncOperation(content); +}; + +module.exports.pitch = function(remainingRequest, precedingRequest, data) { + if (someCondition()) { + return "module.exports = require(" + JSON.stringify("-!" + remainingRequest) + ");"; + } +}; +``` + +The steps above would be shortened to: + +``` diff +|- a-loader `pitch` + |- b-loader `pitch` returns a module +|- a-loader normal execution +``` + +See the [bundle-loader](https://github.com/webpack-contrib/bundle-loader) for a good example of how this process can be used in a more meaningful way. + ## The Loader Context