webpack源碼之loader機(jī)制詳解
loader概念
loader是用來加載處理各種形式的資源,本質(zhì)上是一個(gè)函數(shù), 接受文件作為參數(shù),返回轉(zhuǎn)化后的結(jié)構(gòu)。
loader 用于對(duì)模塊的源代碼進(jìn)行轉(zhuǎn)換。loader 可以使你在 import 或"加載"模塊時(shí)預(yù)處理文件。因此,loader 類似于其他構(gòu)建工具中“任務(wù)(task)”,并提供了處理前端構(gòu)建步驟的強(qiáng)大方法。loader 可以將文件從不同的語言(如 TypeScript)轉(zhuǎn)換為 JavaScript,或?qū)?nèi)聯(lián)圖像轉(zhuǎn)換為 data URL。loader 甚至允許你直接在 JavaScript 模塊中 import CSS文件!
loader和plugin區(qū)別
之前一篇文章中介紹了plugin機(jī)制,和今天研究的對(duì)象loader,他們兩者在一起極大的拓展了webpack的功能。它們的區(qū)別就是loader是用來對(duì)模塊的源代碼進(jìn)行轉(zhuǎn)換,而插件目的在于解決 loader 無法實(shí)現(xiàn)的其他事。為什么這么多說呢?因?yàn)閜lugin可以在任何階段調(diào)用,能夠跨Loader進(jìn)一步加工Loader的輸出,在構(gòu)建運(yùn)行期間,觸發(fā)事件,執(zhí)行預(yù)先注冊(cè)的回調(diào),使用compilation對(duì)象做一些更底層的事情。
loader用法
配置
module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' } ] } ] }
內(nèi)聯(lián)
import Styles from 'style-loader!css-loader?modules!./styles.css';
CLI
webpack --module-bind 'css=style-loader!css-loader'
說明 上面三種使用方法作用都是將一組鏈?zhǔn)降?loader, 按照從右往左的順序執(zhí)行,loader 鏈中的第一個(gè) loader 返回值給下一個(gè) loader。先使用css-loader解析 @import 和 url()路徑中指定的css內(nèi)容,然后用style-loader 會(huì)把原來的 CSS 代碼插入頁面中的一個(gè) style 標(biāo)簽中。
loader實(shí)現(xiàn)
//將css插入到head標(biāo)簽內(nèi)部 module.exports = function (source) { let script = (` let style = document.createElement("style"); style.innerText = ${JSON.stringify(source)}; document.head.appendChild(style); `); return script; } //使用方式1 resolveLoader: { modules: [path.resolve('node_modules'), path.resolve(__dirname, 'src', 'loaders')] }, { test: /\.css$/, use: ['style-loader'] }, //使用方式2 //將自己寫的loaders發(fā)布到npm倉庫,然后添加到依賴,按照方式1中的配置方式使用即可
說明 上面是一個(gè)簡(jiǎn)單的loader實(shí)現(xiàn),同步的方式執(zhí)行,相當(dāng)于實(shí)現(xiàn)了style-loader的功能。
loader原理
function iteratePitchingLoaders(options, loaderContext, callback) { var currentLoaderObject = loaderContext.loaders[loaderContext.loaderIndex]; // load loader module loadLoader(currentLoaderObject, function(err) { var fn = currentLoaderObject.pitch; runSyncOrAsync( fn, loaderContext, [loaderContext.remainingRequest, loaderContext.previousRequest, currentLoaderObject.data = {}], function(err) { if(err) return callback(err); var args = Array.prototype.slice.call(arguments, 1); if(args.length > 0) { loaderContext.loaderIndex--; iterateNormalLoaders(options, loaderContext, args, callback); } else { iteratePitchingLoaders(options, loaderContext, callback); } } ); }); }
說明 上面是webpack源碼中l(wèi)oader執(zhí)行關(guān)鍵步驟,遞歸的方式執(zhí)行l(wèi)oader,執(zhí)行機(jī)流程似于express中間件機(jī)制
參考源碼
- webpack: "4.4.1"
- webpack-cli: "2.0.13"
參考文檔
https://webpack.js.org/concepts/loaders/
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
javascript解決innerText瀏覽器兼容問題思路代碼
innerText瀏覽器兼容這塊始終都是一個(gè)問題,下面與大家分享下使用javascript解決,感興趣的朋友可以參考下哈,希望對(duì)你有所幫助2013-05-05javascript 限制輸入和粘貼(IE,firefox測(cè)試通過)
javascript 限制輸入和粘貼 IE和火狐2.x、火狐3.x下測(cè)試通過2008-11-11js控制文本框只輸入數(shù)字和小數(shù)點(diǎn)的方法
這篇文章主要介紹了js控制文本框只輸入數(shù)字和小數(shù)點(diǎn)的方法,實(shí)例分析了javascript使用正則表達(dá)式實(shí)現(xiàn)限制數(shù)字和小數(shù)點(diǎn)的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03通過JS 獲取Mouse Position(鼠標(biāo)坐標(biāo))的代碼
最近我發(fā)現(xiàn)在webpage中獲取空間的絕對(duì)坐標(biāo)時(shí),如果有滾動(dòng)條就會(huì)有錯(cuò),后來用無名發(fā)現(xiàn)的方法得以解決。2009-09-09Javascript的無new構(gòu)建實(shí)例詳解
這篇文章主要介紹了Javascript的無new構(gòu)建實(shí)例詳解的相關(guān)資料,小編感覺介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-05-05