webpack源碼之loader機制詳解
loader概念
loader是用來加載處理各種形式的資源,本質上是一個函數(shù), 接受文件作為參數(shù),返回轉化后的結構。
loader 用于對模塊的源代碼進行轉換。loader 可以使你在 import 或"加載"模塊時預處理文件。因此,loader 類似于其他構建工具中“任務(task)”,并提供了處理前端構建步驟的強大方法。loader 可以將文件從不同的語言(如 TypeScript)轉換為 JavaScript,或將內(nèi)聯(lián)圖像轉換為 data URL。loader 甚至允許你直接在 JavaScript 模塊中 import CSS文件!
loader和plugin區(qū)別
之前一篇文章中介紹了plugin機制,和今天研究的對象loader,他們兩者在一起極大的拓展了webpack的功能。它們的區(qū)別就是loader是用來對模塊的源代碼進行轉換,而插件目的在于解決 loader 無法實現(xiàn)的其他事。為什么這么多說呢?因為plugin可以在任何階段調用,能夠跨Loader進一步加工Loader的輸出,在構建運行期間,觸發(fā)事件,執(zhí)行預先注冊的回調,使用compilation對象做一些更底層的事情。
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'
說明 上面三種使用方法作用都是將一組鏈式的 loader, 按照從右往左的順序執(zhí)行,loader 鏈中的第一個 loader 返回值給下一個 loader。先使用css-loader解析 @import 和 url()路徑中指定的css內(nèi)容,然后用style-loader 會把原來的 CSS 代碼插入頁面中的一個 style 標簽中。
loader實現(xiàn)
//將css插入到head標簽內(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中的配置方式使用即可
說明 上面是一個簡單的loader實現(xiàn),同步的方式執(zhí)行,相當于實現(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í)行關鍵步驟,遞歸的方式執(zhí)行l(wèi)oader,執(zhí)行機流程似于express中間件機制
參考源碼
- webpack: "4.4.1"
- webpack-cli: "2.0.13"
參考文檔
https://webpack.js.org/concepts/loaders/
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
webpack 動態(tài)批量加載文件的實現(xiàn)方法
這篇文章主要介紹了webpack 動態(tài)批量加載文件的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03
使用JavaScript?將數(shù)據(jù)網(wǎng)格綁定到?GraphQL?服務的操作方法
GraphQL是管理JavaScript應用程序中數(shù)據(jù)的優(yōu)秀工具,本教程展示了GraphQL和SpreadJS如何簡單地構建應用程序,?GraphQL?和?SpreadJS都有更多功能可供探索,因此您可以做的事情遠遠超出了這個示例,感興趣的朋友一起看看吧2023-11-11
uni-app調取接口的3種方式以及封裝uni.request()詳解
我們在實際工作中要將數(shù)據(jù)傳輸?shù)椒掌鞫?從服務器端獲取信息,都是通過接口的形式,下面這篇文章主要給大家介紹了關于uni-app調取接口的3種方式以及封裝uni.request()的相關資料,需要的朋友可以參考下2022-08-08
JS使用遮罩實現(xiàn)點擊某區(qū)域以外時彈窗的彈出與關閉功能示例
這篇文章主要介紹了JS使用遮罩實現(xiàn)點擊某區(qū)域以外時彈窗的彈出與關閉功能,結合實例形式分析了javascript事件響應及頁面元素屬性動態(tài)操作彈出與關閉遮罩層相關實現(xiàn)技巧,需要的朋友可以參考下2018-07-07
JavaScript使用WebSocket實現(xiàn)實時通信的技術詳解
WebSocket作為一種高效的通信協(xié)議,為開發(fā)者提供了一種在客戶端和服務器之間進行全雙工通信的方法,本文將深入探討WebSocket技術,并提供實戰(zhàn)代碼示例2024-04-04

