- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > web開(kāi)發(fā) >
- Webpack中Loader和Plugin的區別是什么
這篇文章主要介紹“Webpack中Loader和Plugin的區別是什么”,在日常操作中,相信很多人在Webpack中Loader和Plugin的區別是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對大家解答”Webpack中Loader和Plugin的區別是什么”的疑惑有所幫助!接下來(lái),請跟著(zhù)小編一起來(lái)學(xué)習吧!
前面兩節我們有提到Loader與Plugin對應的概念,先來(lái)回顧下
loader 是文件加載器,能夠加載資源文件,并對這些文件進(jìn)行一些處理,諸如編譯、壓縮等,最終一起打包到指定的文件中
plugin 賦予了 webpack 各種靈活的功能,例如打包優(yōu)化、資源管理、環(huán)境變量注入等,目的是解決 loader 無(wú)法實(shí)現的其他事
從整個(gè)運行時(shí)機上來(lái)看,如下圖所示:
可以看到,兩者在運行時(shí)機上的區別:
loader 運行在打包文件之前
plugins 在整個(gè)編譯周期都起作用
在Webpack 運行的生命周期中會(huì )廣播出許多事件,Plugin 可以監聽(tīng)這些事件,在合適的時(shí)機通過(guò)Webpack提供的 API改變輸出結果
對于loader,實(shí)質(zhì)是一個(gè)轉換器,將A文件進(jìn)行編譯形成B文件,操作的是文件,比如將A.scss或A.less轉變?yōu)锽.css,單純的文件轉換過(guò)程
在編寫(xiě) loader 前,我們首先需要了解 loader 的本質(zhì)
其本質(zhì)為函數,函數中的 this 作為上下文會(huì )被 webpack 填充,因此我們不能將 loader設為一個(gè)箭頭函數
函數接受一個(gè)參數,為 webpack 傳遞給 loader 的文件源內容
函數中 this 是由 webpack 提供的對象,能夠獲取當前 loader 所需要的各種信息
函數中有異步操作或同步操作,異步操作通過(guò) this.callback返回,返回值要求為 string 或者 Buffer
代碼如下所示:
// 導出一個(gè)函數,source為webpack傳遞給loader的文件源內容 module.exports = function(source) { const content = doSomeThing2JsString(source); // 如果 loader 配置了 options 對象,那么this.query將指向 options const options = this.query; // 可以用作解析其他模塊路徑的上下文 console.log('this.context'); /* * this.callback 參數: * error:Error | null,當 loader 出錯時(shí)向外拋出一個(gè) error * content:String | Buffer,經(jīng)過(guò) loader 編譯后需要導出的內容 * sourceMap:為方便調試生成的編譯后內容的 source map * ast:本次編譯生成的 AST 靜態(tài)語(yǔ)法樹(shù),之后執行的 loader 可以直接使用這個(gè) AST,進(jìn)而省去重復生成 AST 的過(guò)程 */ this.callback(null, content); // 異步 return content; // 同步 }
一般在編寫(xiě)loader的過(guò)程中,保持功能單一,避免做多種功能
如less文件轉換成 css文件也不是一步到位,而是 less-loader、css-loader、style-loader幾個(gè) loader的鏈式調用才能完成轉換
由于webpack基于發(fā)布訂閱模式,在運行的生命周期中會(huì )廣播出許多事件,插件通過(guò)監聽(tīng)這些事件,就可以在特定的階段執行自己的插件任務(wù)
在之前也了解過(guò),webpack編譯會(huì )創(chuàng )建兩個(gè)核心對象:
compiler:包含了 webpack 環(huán)境的所有的配置信息,包括 options,loader 和 plugin,和 webpack 整個(gè)生命周期相關(guān)的鉤子
compilation:作為 plugin 內置事件回調函數的參數,包含了當前的模塊資源、編譯生成資源、變化的文件以及被跟蹤依賴(lài)的狀態(tài)信息。當檢測到一個(gè)文件變化,一次新的 Compilation 將被創(chuàng )建
如果自己要實(shí)現plugin,也需要遵循一定的規范:
插件必須是一個(gè)函數或者是一個(gè)包含 apply 方法的對象,這樣才能訪(fǎng)問(wèn)compiler實(shí)例
傳給每個(gè)插件的 compiler 和 compilation 對象都是同一個(gè)引用,因此不建議修改
異步的事件需要在插件處理完任務(wù)時(shí)調用回調函數通知 Webpack 進(jìn)入下一個(gè)流程,不然會(huì )卡住
實(shí)現plugin的模板如下:
class MyPlugin { // Webpack 會(huì )調用 MyPlugin 實(shí)例的 apply 方法給插件實(shí)例傳入 compiler 對象 apply (compiler) { // 找到合適的事件鉤子,實(shí)現自己的插件功能 compiler.hooks.emit.tap('MyPlugin', compilation => { // compilation: 當前打包構建流程的上下文 console.log(compilation); // do something... }) } }
在 emit 事件發(fā)生時(shí),代表源文件的轉換和組裝已經(jīng)完成,可以讀取到最終將輸出的資源、代碼塊、模塊及其依賴(lài),并且可以修改輸出資源的內容
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系站長(cháng)郵箱:ts@56dr.com進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2 建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站