webpack plugn 插件原理

從上文提煉出 webpack 的一些主要流程

init => run(前兩個一般不用) => compile(編譯開始的時候) => compilation(準備編譯的整個過程) => make(開始編譯) => afterCompile(編譯結束) => seal(對代碼進行封裝,比如優化、合併...) => codeGenerate(生成代碼) => emit(發射,把文件寫到硬盤裏面) => done

插件,就是找個地方插進去

比如:imagemin-webpack-pluginclean-webpack-plugin

imagemin-webpack-plugin

  • 這是一個壓縮圖片的插件
  • 文件目錄非常簡單
  • 主要看 apply 這個函數
  • 根據看源碼的步驟,跳過聲明
  • 直接看最後的 if else,因爲我們一般使用的是 webpack 4 以上的版本,所以進入 compiler.hooks 分支(見代碼備註)
  • 發現他監聽了 emit 這個事件
  • 直接看函數名字我們就能知道他的主要功能(優化項目中圖片和其他外部圖片)
  • 對 compilation.assets (此次編譯的文件)進行 map 操作,用 testFunction 判斷是否是圖片文件,然後執行 optimizeImage 這個方法進行圖片優化(這裏用到了 imagemin 這個庫)

這個插件非常簡單

clean-webpack-plugin

  • 這是一個清理 webpack 的輸出目錄的插件
  • 分析這個插件之前,我們先思考如果我們要寫這個插件,我們應該監聽哪個鉤子函數?如果是init 可能可以?但是有點不妥,因爲有可能初始化的過程中會報錯,這樣就不會產生新的文件,所以就沒有必要清除之前的文件
  • 很顯然我們應該在 emit (寫文件之前)去清理文件
  • 果然他也是在監聽 emit,從而去執行 handleInitial 和 removeFiles(看函數名字就知道了,這倆函數邏輯非常簡單,這裏暫不分析了)
  • 但是細心的你肯定也發現了,爲什麼下面他還監聽了 done?
  • 因爲可能 emit 的時候也會產生一些垃圾、臨時文件,所以也需要清理

ProvidePlugin

  • 這個插件主要用於注入全局變量,比如說每個文件都需要用到 JQuery,你需要每個文件都引入,
    用這個插件他會幫你自動引入,你直接用就好了
  • 使用方法很簡單
  • 在選項中聲明好,只要你用到了 $ 或者 JQuery,就會自動引入 JQuery
  • vue 同理

  • 同樣,如果是我們寫這個插件,我們應該監聽哪個鉤子函數?

  • 猜測應該是在 compilation 或者 make 階段

  • 這個插件就不一樣了,他主要監聽的是 nft 的 parse 階段
  • 我們來看這個 handle 函數做了什麼
  • 遍歷了 definition (就是選項哪個對象: {$: 'jquery', vue: [....]})
  • 分析所有的表達式(expression),如果你用到了哪些,就幫你直接在依賴中添加(等價於幫你自動 import)
  • 主要思路

正式因爲插件可以在任何階段進行魔改,所以 webpack 功能非常強大

常用插件

18個常用 webpack插件,總會有適合你的!

loader 與 plugin 的區別

loader 沒啥問題,就是轉換文件
它豐富了webpack本身(難道 loader 沒有豐富 webpack 嗎?)
針對是loader結束後(plugin 可以對任何階段進行操作)
它並不直接操作文件(他可以直接操作文件,甚至可以刪文件)
就這些修正

loader 比較簡單,在 make 階段中執行,單純的文件轉換過程,而 plugin 他是對 webpack 的功能進行拓展,他是基於事件機制,對 webpack 的每個階段都可以進行介入,做一些功能(任何你想做的)。

如何自己寫一個 plugin

  • 必須名聲一個 class

  • 必須有一個 apply 函數,並且接受一個 compiler 參數

  • 接下來對某一個鉤子進行監聽,在寫你的主要邏輯

  • 舉例

  • 一個簡單的在 done 之後打印一句話,和使用方法

  • 用到的主要知識

  • 對 webpack hooks 的瞭解

  • 對編譯原理的瞭解

  • 對 chunk、hash、module、dep、factor 等概念的理解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章