webpack中關于pitching loader
的文檔比較不清楚:
The loaders are 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 for metadata. The pitch method on the loaders is called from left to right before the loaders are called. 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.
比如a!b!c!module
, 正常調用順序應該是c、b、a口芍,但是真正調用順序是
a(pitch)昵宇、b(pitch)喘帚、c(pitch)负溪、c蓬推、b、a俺抽, 如果其中任何一個pitching loader返回了值就相當于在它以及它右邊的loader已經執(zhí)行完畢敞映。
比如如果b返回了字符串"result b", 接下來只有a會被系統(tǒng)執(zhí)行,且a的loader收到的參數(shù)是result b
磷斧。
也就是說pitching loader
的初衷是為了提升效率振愿,少執(zhí)行幾個loader。
然而這樣的機會并不多瞳抓。更為常用的是它的另一個用途埃疫。
根據(jù)官方文檔:
In the complex case, when multiple loaders are chained, only the last loader gets the resource file and only the first loader is expected to give back one or two values (JavaScript and SourceMap). Values that any other loader give back are passed to the previous loader.
loader根據(jù)返回值可以分為兩種,一種是返回js代碼(一個module的代碼孩哑,含有類似module.export
語句)的loader栓霜,還有不能作為最左邊loader的其他loader
問題是有時候我們想把兩個第一種loader chain起來,比如style-loader!css-loader!
問題是css-loader
的返回值是一串js代碼横蜒,如果按正常方式寫style-loader
的參數(shù)就是一串代碼字符串胳蛮。就算eval
了也不一定拿到什么值
eval('module.export="result";console.log("hello world")') === "hello world"
為了解決這種問題,我們需要在style-loader
里執(zhí)行require(css-loader!resouce)
, 這會把css-loader
跑一遍丛晌,也就是說如果按正常順序執(zhí)行css-loader
會跑兩遍(第一遍拿到的js代碼用不了), 為了只執(zhí)行一次仅炊,style-loader
利用了pitching
, 在pitching
函數(shù)里require(css-loader!resouce)
。然后返回js代碼(style-loader能夠作為最左邊loader)