1,webpack背景知識
一款前端項目開發構建工具。或者用gulp。
前后端分離的開發環境,解析不同的資源文件,統一打包分包,按需加載,網站優化等。
主要構成,入口/出口,loader和plugins、model、rules等配置,webpack自身提供插件如:分析、壓縮、html、 provider等。
自定義的plugins,需要了解一些模塊化、語法樹、compiler、compilation、
2,webpack 自定義插件的開發
2.1、創建一個plugins
- 構建函數
- 擴展 apply 方法
- 指定webpack自身的事件鈎子
- 處理webpack內部實例的特定數據
- 功能完成后,調用webpack提供的回調
// 自定義事件的插件函數,也可以寫成class的形式,但是內部apply方法不能用 箭頭函數。
function myPlugin () { } // 對 插件函數擴展 apply 方法 myPlugin.prototype.apply = function(compiler) {
// webpack提供的編譯函數模板,監聽webpack的鈎子事件,然后會觸發 compilation,和插件執行完成的回調。 compiler.plugin('webpacksEventHook', function(compilation,callback) { console.log('this is customer plugins'); callback(); }); }
2.2、webpack插件的鈎子函數
webpack在打包過程中有自己的生命周期函數,webpack打包過程做了分類,於是就有了很多不同類型的插件。
其中有兩個重要的對象:compilation,compiler
compiler 包含webpack的所有配置信息(webpack.config.js),作為 webpack 的實例在啟動時被初始化。
compilation 包含當前模塊,編譯文件,例如在開發環境,當文件發生變化,就會有一個新的 compilation。
以下內容就是一個webpack的自定義插件。
function MyPlugin(options) { this.options = options; } MyPlugin.prototype.apply = function(compiler) { console.log('開始執行插件') compiler.plugin('compile', function () { console.log('webpack 編譯器開始編譯...-----') }) compiler.plugin('compilation', function (compilation) { console.log('編譯器開始一個新的編譯任務...-----') compilation.plugin('optimize', function () { console.log('編譯器開始優化文件...') }) }) compiler.plugin('done', function () { console.log('打包完成......') }) }; module.exports = MyPlugin;
舉例說明,通過emit鈎子獲取編譯后塊文件包含的路徑,webpack高版本api有變化不支持,使用webpack2.
compiler.plugin('emit', function (compilation, callback) { // compilation.chunks 存放所有代碼塊,是一個數組 compilation.chunks.forEach(function (chunk) { // chunk 代碼塊 // 代碼塊由模塊組成,讀取模塊 chunk.forEachModule(function (module) { // module 模塊 // module.fileDependencies 訪問當前模塊需要的依賴,即是文件路徑。 module.fileDependencies.forEach(function (filepath) { console.log(filepath) }) }) }) // emit 是異步事件,AsyncSeriesHook,異步事件都需要調用callback。有點像英語里的及物動詞和不及物動詞 callback(); })