如何寫一個webpack plugin,幫你升職加薪


我們經常使用到webpack的插件功能,那如何開發一個自定義的插件呢?首先創建插件比創建 loader 更加高級,webpack 插件由以下組成:
  • 一個 JavaScript 命名函數。
  • 在插件函數的 prototype 上定義一個 apply 方法。
  • 指定一個綁定到 webpack 自身的事件鈎子
  • 處理 webpack 內部實例的特定數據。
  • 功能完成后調用 webpack 提供的回調。
下面就一點點的帶你開發一個自定義的webpack plugin.
先說說webpack插件中的兩位重要人物,Compiler和Compliation
  • compiler 對象代表了完整的 webpack 環境配置。這個對象在啟動 webpack 時被一次性建立,並配置好所有可操作的設置,包括 options,loader 和 plugin。當在 webpack 環境中應用一個插件時,插件將收到此 compiler 對象的引用。可以使用它來訪問 webpack 的主環境。
  • compilation 對象代表了一次資源版本構建。當運行 webpack 開發環境中間件時,每當檢測到一個文件變化,就會創建一個新的 compilation,從而生成一組新的編譯資源。一個 compilation 對象表現了當前的模塊資源、編譯生成資源、變化的文件、以及被跟蹤依賴的狀態信息。compilation 對象也提供了很多關鍵時機的回調,以供插件做自定義處理時選擇使用。
基礎插件架構
///src/plugins/helloPlugin.js
// 命名函數。
function HelloPlugin(options) {
    // 使用 options 設置插件實例……
    console.log(options);
}

//插件函數的 prototype 上定義一個 apply 方法
HelloPlugin.prototype.apply = compiler => {
    //hooks
     compiler.hooks.done.tap('HelloPlugin', status => {
        console.log(status.toJson());

    })
    
    // 舊版本的相關鈎子
    //compiler.plugin('done' , () => {
      //  console.log('hello world');
    //})

    // 設置回調來訪問 compilation 對象:
    //compiler.plugin('compilation', compilation => {

        // 現在,設置回調來訪問 compilation 中的步驟:
       // compilation.plugin('optimize', () => {
            console.log('optimize');
        //})

    //})
}

module.exports = HelloPlugin

  

//webpack.config.js

const HelloPlugin = require('./src/plugins/helloPlugin')
plugins: [
        new HelloPlugin({options:true})
    ]

  

這樣基礎架構就搭建完成了.
認識一下事件鈎子
生命周期鈎子函數,是由 compiler 暴露,可以通過如下方式訪問:
compiler.hooks.someHook.tap(...)

  

取決於不同的鈎子類型,也可以在某些鈎子上訪問 tapAsync 和 tapPromise。
例如
// 在處理來自webpack選項的entry配置后調用
    compiler.hooks.entryOption.tap('HelloPlugin', (context, entry) => {
        console.log(1,context, entry);
    })
 
也支持自定義鈎子函數
// 自定義hook
 const SyncHook = require('tapable').SyncHook;
// 具有 `apply` 方法……
if (compiler.hooks.myCustomHook) throw new Error('Already in use');
compiler.hooks.myCustomHook = new SyncHook(['a', 'b', 'c'])
// 在你想要觸發鈎子的位置/時機下調用……
compiler.hooks.myCustomHook.call(a, b, c);  

  

學會了webpack的事件生命周期鈎子函數,那么下面我們就開始着手寫一個webpack插件.
生成一個展示打包完成后的文件列表,ok,直接上代碼
// 命名函數。
function HelloPlugin(options) {
    // 使用 options 設置插件實例……
    console.log(options);
}

//插件函數的 prototype 上定義一個 apply 方法
HelloPlugin.prototype.apply = compiler => {
    // 在將資產釋放到輸出目錄后調用。
    compiler.hooks.emit.tapAsync('HelloPlugin', (compilation, callback) => {
        let fileList = `## in this build:\n\n`

        console.log(compilation.assets);
        const assets = compilation.assets
        for(let key in assets){
            console.log(key);
            fileList+=`${key}\n`
        }
        compilation.assets['fileList.md'] = {
            source:()=>{return fileList},
            size:() => {return fileList.length}
        }
        callback()
    })
}
module.exports = HelloPlugin

  

看,根據不同的webpack生命周期事件鈎子函數,處理不同的邏輯,就可以完成一個webpack的plugin了,你學會了嗎?
關於深入學習請參考:

如果覺得文章不錯,可以給小編發個紅包給予鼓勵.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM