自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官:說(shuō)說(shuō)Webpack中Loader和Plugin的區(qū)別?編寫(xiě)Loader,Plugin的思路?

開(kāi)發(fā) 前端
由于webpack基于發(fā)布訂閱模式,在運(yùn)行的生命周期中會(huì)廣播出許多事件,插件通過(guò)監(jiān)聽(tīng)這些事件,就可以在特定的階段執(zhí)行自己的插件任務(wù)

[[396986]]

一、區(qū)別

前面兩節(jié)我們有提到Loader與Plugin對(duì)應(yīng)的概念,先來(lái)回顧下

  • loader 是文件加載器,能夠加載資源文件,并對(duì)這些文件進(jìn)行一些處理,諸如編譯、壓縮等,最終一起打包到指定的文件中
  • plugin 賦予了 webpack 各種靈活的功能,例如打包優(yōu)化、資源管理、環(huán)境變量注入等,目的是解決 loader 無(wú)法實(shí)現(xiàn)的其他事

從整個(gè)運(yùn)行時(shí)機(jī)上來(lái)看,如下圖所示:

可以看到,兩者在運(yùn)行時(shí)機(jī)上的區(qū)別:

  • loader 運(yùn)行在打包文件之前
  • plugins 在整個(gè)編譯周期都起作用

在Webpack 運(yùn)行的生命周期中會(huì)廣播出許多事件,Plugin 可以監(jiān)聽(tīng)這些事件,在合適的時(shí)機(jī)通過(guò)Webpack提供的 API改變輸出結(jié)果

對(duì)于loader,實(shí)質(zhì)是一個(gè)轉(zhuǎn)換器,將A文件進(jìn)行編譯形成B文件,操作的是文件,比如將A.scss或A.less轉(zhuǎn)變?yōu)锽.css,單純的文件轉(zhuǎn)換過(guò)程

二、編寫(xiě)loader

在編寫(xiě) loader 前,我們首先需要了解 loader 的本質(zhì)

其本質(zhì)為函數(shù),函數(shù)中的 this 作為上下文會(huì)被 webpack 填充,因此我們不能將 loader設(shè)為一個(gè)箭頭函數(shù)

函數(shù)接受一個(gè)參數(shù),為 webpack 傳遞給 loader 的文件源內(nèi)容

函數(shù)中 this 是由 webpack 提供的對(duì)象,能夠獲取當(dāng)前 loader 所需要的各種信息

函數(shù)中有異步操作或同步操作,異步操作通過(guò) this.callback返回,返回值要求為 string 或者 Buffer

代碼如下所示:

  1. // 導(dǎo)出一個(gè)函數(shù),source為webpack傳遞給loader的文件源內(nèi)容 
  2. module.exports = function(source) { 
  3.     const content = doSomeThing2JsString(source); 
  4.      
  5.     // 如果 loader 配置了 options 對(duì)象,那么this.query將指向 options 
  6.     const options = this.query; 
  7.      
  8.     // 可以用作解析其他模塊路徑的上下文 
  9.     console.log('this.context'); 
  10.      
  11.     /* 
  12.      * this.callback 參數(shù): 
  13.      * error:Error | null,當(dāng) loader 出錯(cuò)時(shí)向外拋出一個(gè) error 
  14.      * content:String | Buffer,經(jīng)過(guò) loader 編譯后需要導(dǎo)出的內(nèi)容 
  15.      * sourceMap:為方便調(diào)試生成的編譯后內(nèi)容的 source map 
  16.      * ast:本次編譯生成的 AST 靜態(tài)語(yǔ)法樹(shù),之后執(zhí)行的 loader 可以直接使用這個(gè) AST,進(jìn)而省去重復(fù)生成 AST 的過(guò)程 
  17.      */ 
  18.     this.callback(null, content); // 異步 
  19.     return content; // 同步 

一般在編寫(xiě)loader的過(guò)程中,保持功能單一,避免做多種功能

如less文件轉(zhuǎn)換成 css文件也不是一步到位,而是 less-loader、css-loader、style-loader幾個(gè) loader的鏈?zhǔn)秸{(diào)用才能完成轉(zhuǎn)換

三、編寫(xiě)plugin

由于webpack基于發(fā)布訂閱模式,在運(yùn)行的生命周期中會(huì)廣播出許多事件,插件通過(guò)監(jiān)聽(tīng)這些事件,就可以在特定的階段執(zhí)行自己的插件任務(wù)

在之前也了解過(guò),webpack編譯會(huì)創(chuàng)建兩個(gè)核心對(duì)象:

  • compiler:包含了 webpack 環(huán)境的所有的配置信息,包括 options,loader 和 plugin,和 webpack 整個(gè)生命周期相關(guān)的鉤子
  • compilation:作為 plugin 內(nèi)置事件回調(diào)函數(shù)的參數(shù),包含了當(dāng)前的模塊資源、編譯生成資源、變化的文件以及被跟蹤依賴的狀態(tài)信息。當(dāng)檢測(cè)到一個(gè)文件變化,一次新的 Compilation 將被創(chuàng)建

如果自己要實(shí)現(xiàn)plugin,也需要遵循一定的規(guī)范:

  • 插件必須是一個(gè)函數(shù)或者是一個(gè)包含 apply 方法的對(duì)象,這樣才能訪問(wèn)compiler實(shí)例
  • 傳給每個(gè)插件的 compiler 和 compilation 對(duì)象都是同一個(gè)引用,因此不建議修改
  • 異步的事件需要在插件處理完任務(wù)時(shí)調(diào)用回調(diào)函數(shù)通知 Webpack 進(jìn)入下一個(gè)流程,不然會(huì)卡住

實(shí)現(xiàn)plugin的模板如下:

  1. class MyPlugin { 
  2.     // Webpack 會(huì)調(diào)用 MyPlugin 實(shí)例的 apply 方法給插件實(shí)例傳入 compiler 對(duì)象 
  3.   apply (compiler) { 
  4.     // 找到合適的事件鉤子,實(shí)現(xiàn)自己的插件功能 
  5.     compiler.hooks.emit.tap('MyPlugin', compilation => { 
  6.         // compilation: 當(dāng)前打包構(gòu)建流程的上下文 
  7.         console.log(compilation); 
  8.          
  9.         // do something... 
  10.     }) 
  11.   } 

在 emit 事件發(fā)生時(shí),代表源文件的轉(zhuǎn)換和組裝已經(jīng)完成,可以讀取到最終將輸出的資源、代碼塊、模塊及其依賴,并且可以修改輸出資源的內(nèi)容

參考文獻(xiàn)

https://webpack.docschina.org/api/loaders/

https://webpack.docschina.org/api/compiler-hooks/

https://segmentfault.com/a/1190000039877943

https://vue3js.cn/interview

 

 

責(zé)任編輯:武曉燕 來(lái)源: S每日一題
相關(guān)推薦

2025-03-07 02:00:00

webpackPlugin開(kāi)發(fā)

2021-06-22 10:43:03

Webpack loader plugin

2021-05-31 05:36:43

WebpackJavaScript 前端

2024-09-20 12:25:16

Webpackchunkbundle

2021-08-12 07:49:25

Git 索引HEAD

2022-03-08 09:16:20

webpack前端開(kāi)發(fā)

2021-09-30 07:57:13

排序算法面試

2021-06-29 09:47:34

ReactSetState機(jī)制

2021-05-08 08:35:33

Webpack前端性能

2021-08-17 07:15:16

Git RebaseGit Merge面試

2024-11-19 15:13:02

2023-12-27 18:16:39

MVCC隔離級(jí)別幻讀

2025-04-16 00:00:01

JWT客戶端存儲(chǔ)加密令

2025-04-08 00:00:00

@AsyncSpring異步

2021-08-19 08:36:22

Git ResetGit Revert版本

2025-03-10 11:40:00

前端開(kāi)發(fā)HTML

2025-03-10 00:00:00

property?attributeHTML

2021-09-13 09:23:52

TypeScript命名空間

2021-10-15 09:53:12

工具

2021-05-06 14:34:12

Webpack熱更新程序
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)