1. 程式人生 > 實用技巧 >【筆記】Tapable原始碼解析圖以及webpack怎樣實現一個外掛plugin

【筆記】Tapable原始碼解析圖以及webpack怎樣實現一個外掛plugin

Tapable原始碼解析圖,如圖所示:

一個webpack plugin由一下幾個步驟組成:

  1. 一個JavaScript類函式。
  2. 在函式原型 (prototype)中定義一個注入compiler物件的apply方法。
  3. apply函式中通過compiler插入指定的事件鉤子,在鉤子回撥中拿到compilation物件
  4. 使用compilation操縱修改webapack內部例項資料。
  5. 非同步外掛,資料處理完後使用callback回撥

開發webpack外掛還需要了解其中兩個核心的物件引用Compiler 和 Compilation,這裡需要理解清楚他們的含義。

  • compiler物件代表了完整的 webpack 環境配置。這個物件在啟動 webpack 時被一次性建立,並配置好所有可操作的設定,包括 options,loader 和 plugin。當在 webpack 環境中應用一個外掛時,外掛將收到此 compiler 物件的引用。可以使用它來訪問 webpack 的主環境。
  • compilation物件代表了一次資源版本構建。當執行 webpack 開發環境中介軟體時,每當檢測到一個檔案變化,就會建立一個新的 compilation,從而生成一組新的編譯資源。一個 compilation 物件表現了當前的模組資源、編譯生成資源、變化的檔案、以及被跟蹤依賴的狀態資訊。compilation 物件也提供了很多關鍵時機的回撥,以供外掛做自定義處理時選擇使用。

實現一個如下需求的外掛,針對某個打包生成的JS,對其內容的頭部新增一個eslint語法檢測的忽略說明,那樣eslint就不會檢測當前打包的js,如下程式碼:

class ignoreEslintPlugin {
  constructor(options) {
    
this.options = options; } apply(compiler) { compiler.hooks.emit.tap('ignoreEslintPlugin', (compilation) => { var topInfo = '/* eslint-disable */\n'; var content = topInfo + compilation.assets[this.options.filename].source(); // console.info(chalk.green(content)) compilation.assets[this
.options.filename] = { source: () => content, size: () => content.length } }) } }

呼叫方式:

new ignoreEslintPlugin({filename: 'common.js'})

我們看下上面程式碼中的這個結構:

compiler.hooks.emit.tap('ignoreEslintPlugin', (compilation) => {
      
})

這一步主要是使用核心物件compiler的emit鉤子,通過.tap方法註冊到webpack中,在輸出構建產物到dist目錄之前執行。 在這裡列出compiler物件的生命週期鉤子
-> beforeRun 清除快取
-> run 註冊快取資料鉤子
-> beforeCompile
-> compile 開始編譯
-> make 從入口分析依賴以及間接依賴模組,建立模組物件
-> buildModule 模組構建
-> normalModuleFactory 構建
-> seal 構建結果封裝, 不可再更改
-> afterCompile 完成構建,快取資料
-> emit 輸出到dist目錄

參考地址:怎樣編寫一個簡單的webpack外掛