大前端工程化之寫一個簡單的webpack外掛

要愛學習鴨發表於2022-02-12

今天寫一個簡單的webpack外掛,來學習一下webpack外掛

webpack外掛機制可以使開發者在webpack構建過程中加入自己的行為,來針對自己專案中的一些需求做一些定製化

首先我們得知道一個外掛是如何組成的:

  1. 定義javascript命名函式
  2. 給這個函式的prototype新增apply方法
  3. 在這個方法內我們可以勾入webpack暴露的鉤子,這些鉤子主要由compiler,compilation兩個物件暴露
  4. 在某個需要勾入的構建回撥中加入自己的處理函式,處理需要處理的資源
  5. 處理完成後呼叫webpack提供的回撥

 

上面提到的 compiler compilation 是外掛開發中用到的兩個重要物件,我理解為compiler代表整個webpack的配置物件,在webpack啟動時就建立,compilation代表單次構建的物件,每次檔案的更改都會建立一個新的compilation物件,可能闡述的不是很完全,可以參照webpack官方文件

compiler 和 compilation 這兩個物件都擴充套件自Tapable類,在觸碰他們的鉤子時根據鉤子觸發的時機呼叫不同的方法,主要有tap,tapAsync,tapPromise三個方法,呼叫形式都是

compilation.hooks.someHook.tap(/* ... */);

說了這麼多,可以通過程式碼加深一下印象,來加深一下外掛基本的組成和使用

// webpack外掛先定義一個js函式
function MyPlugin(options) {

}

// 然後在這個函式的prototype新增apply方法
MyPlugin.prototype.apply = function (compiler) {
    compiler.hooks.emit.tapAsync('MyPlugin',function(compilation, callback) {
        // 在生成檔案中,建立一個頭部字串:
        var filelist = 'In this build:\n\n';
    
        // 遍歷所有編譯過的資原始檔,
        // 對於每個檔名稱,都新增一行內容。
        // 在這裡我們可以做一些我們想做的事情
        for (var filename in compilation.assets) {
          filelist += ('- '+ filename +'\n');
        }
    
        // 將這個列表作為一個新的檔案資源,插入到 webpack 構建中:
        compilation.assets['filelist.md'] = {
          source: function() {
            return filelist;
          },
          size: function() {
            return filelist.length;
          }
        };
    
        callback();
      });
}

module.exports = MyPlugin
const path = require('path')
const MyPlugin = require('./js/plugins/myPlugin')

module.exports = {
    entry: {
        main: './js/main',
        index:'./js/index'
    },
    output: {
        filename:'[name]-[hash].js',
        path:path.join(__dirname,'dist')
    },
    plugins:[
        new MyPlugin() //此處呼叫外掛
    ]
}

 大家有麼有在專案中有自己寫過webpack外掛,可以探討一下?

相關文章