編寫webpack 插件

Webpack插件為第三方開發者釋放了Webpack的最大可能性。利用多級回調開發者可以把他們自己的需要的功能引入到Webpack裡面來。Build插件比Build loader 更進一步。因為你需要理解Webpack底層的東西。要有月底源代碼的準備。

Compiler 和 Compilation

開發插件最重要的兩個資源就是 compiler 和 compilation 對象,理解他們的是擴展Webpack重要的一步

  • compiler對象包涵了Webpack環境所有的的配置信息,這個對象在Webpack啟動時候被構建,並配置上所有的設置選項包括 options,loaders,plugins。當啟用一個插件到Webpack環境的時候,這個插件就會接受一個指向compiler的參數。運用這個參數來獲取到Webpack環境
  • compilation代表了一個單一構建版本的物料。在webpack中間件運行時,每當一個文件發生改變時就會產生一個新的compilation從而產生一個新的變異後的物料集合。compilation列出了很多關於當前模塊資源的信息,編譯後的資源信息,改動過的文件,以及監聽過的依賴。compilation也提供了插件需要自定義功能的回調點。

這兩個組件在所有的Webpack插件中都是不可分割的一部分(特別是compilation),所以對於開發者來說熟悉這兩個組件的源文件將是你受益很多:

  • Compiler 源文件
  • Compilation 源文件

插件基本結構

Plugins是可以用自身原型方法apply來實例化的對象。apply只在安裝插件被Webpack compiler執行一次。apply方法傳入一個Webpck compiler的引用,來訪問編譯器回調。

一個簡單的插件結構:

function HelloWorldPlugin(options) {n // Setup the plugin instance with options...n}nnHelloWorldPlugin.prototype.apply = function(compiler) {n compiler.plugin(done, function() {n console.log(Hello World!); n });n};nnmodule.exports = HelloWorldPlugin;n

安裝插件時, 只需要將它的一個實例放到 Webpack config plugins 數組裡面:

var HelloWorldPlugin = require(hello-world);nnvar webpackConfig = {n // ... config settings here ...n plugins: [n new HelloWorldPlugin({options: true})n ]n};n

訪問 compilation

使用compiler對象,你可能需要綁定帶有各個新compilation的引用的回調函數。這些compilation提供回調函數連接成許多構建過程中的步驟。

function HelloCompilationPlugin(options) {}nnHelloCompilationPlugin.prototype.apply = function(compiler) {nn // Setup callback for accessing a compilation:n compiler.plugin("compilation", function(compilation) {nn // Now setup callbacks for accessing compilation steps:n compilation.plugin("optimize", function() {n console.log("Assets are being optimized.");n });n });n});nnmodule.exports = HelloCompilationPlugin;n

更多關於在compiler, compilation等對象中哪些回調有用,看一下

plugins API

非同步編譯插件

有些compilation插件的步驟時非同步的,並且會傳入一個當你的插件運行完成時候必須調用的回調函數。

function HelloAsyncPlugin(options) {}nnHelloAsyncPlugin.prototype.apply = function(compiler) {n compiler.plugin("emit", function(compilation, callback) {nn // Do something async...n setTimeout(function() {n console.log("Done with async work...");n callback();n }, 1000);nn });n});nnmodule.exports = HelloAsyncPlugin;n

例子

我們了解了Webpack compiler和各個compilations,我們就可以用它們來創造無盡的可能。我們可以重定當前文件的格式,生成一個衍生文件,或者製造出一個全新的assets

下面我們將寫一個簡單的插件,生成一個filelist.md文件,裡面的內容是,列出我們build的所有asset 文件。

function FileListPlugin(options) {}nnFileListPlugin.prototype.apply = function(compiler) {n compiler.plugin(emit, function(compilation, callback) {n // Create a header string for the generated file:n var filelist = In this build:nn;nn // Loop through all compiled assets,n // adding a new line item for each filename.n for (var filename in compilation.assets) {n filelist += (- + filename +n);n }nn // Insert this list into the Webpack build as a new file asset:n compilation.assets[filelist.md] = {n source: function() {n return filelist;n },n size: function() {n return filelist.length;n }n };nn callback();n });n};nnmodule.exports = FileListPlugin;n

  • 同期發布在我的個人博客里 編寫webpack 插件

推薦閱讀:

Udacity項目二-網頁優化
web前端,該不該辭職?
Vue.js 2.0 快速上手 - 基礎篇
ECMAScript中的對象和DOM BOM對象是一個概念么?

TAG:webpack | 前端工程化 | 前端开发 |