大前端工程化之寫一個簡單的webpack插件
今天寫一個簡單的webpack插件,來學習一下webpack插件
webpack插件機制可以使開發者在webpack構建過程中加入自己的行為,來針對自己項目中的一些需求做一些訂製化
首先我們得知道一個插件是如何組成的:
- 定義javascript命名函數
- 給這個函數的prototype添加apply方法
- 在這個方法內我們可以勾入webpack暴露的鉤子,這些鉤子主要由compiler,compilation兩個對象暴露
- 在某個需要勾入的構建回調中加入自己的處理函數,處理需要處理的資源
- 處理完成後調用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插件,可以探討一下😊