為webpack編寫一個(gè)plugin

0烫饼、基本概念

插件是webpack的支柱功能,極大地強(qiáng)化了webpack的構(gòu)建能力倘屹。

webpack 插件由以下組成:
  • 一個(gè) JavaScript 命名函數(shù)拍谐。
  • 在插件函數(shù)的 prototype 上定義一個(gè) apply 方法。
  • 指定一個(gè)綁定到 webpack 自身的事件鉤子砍濒。
  • 處理 webpack 內(nèi)部實(shí)例的特定數(shù)據(jù)赶掖。
  • 功能完成后調(diào)用 webpack 提供的回調(diào)。

1锐膜、webpack Hooks

一個(gè)簡單的例子:
function MyExampleWebpackPlugin() {
};

// 在插件函數(shù)的 prototype 上定義一個(gè) `apply` 方法种远。
MyExampleWebpackPlugin.prototype.apply = function(compiler) {
  // 指定一個(gè)掛載到 webpack 自身的事件鉤子。
  compiler.plugin('webpacksEventHook', function(compilation, callback) {
    console.log("This is an example plugin!!!");
    // 功能完成后調(diào)用 webpack 提供的回調(diào)拖陆。
    callback();
  });
};

以上是編寫一個(gè)插件的基本格式叹誉,關(guān)于 webpacksEventHook 可以查看文檔 webpack 的 Hooks

列舉幾種hooks:
  • entryOption SyncBailHook, webpack 處理完 entry 配置項(xiàng)后觸發(fā)
  • afterPlugins SyncHook, 處理完初始化插件后觸發(fā)
  • afterResolvers SyncHook, Resolve 安裝完成后觸發(fā)
  • environment SyncHook, environment 準(zhǔn)備好后觸發(fā)
  • emit AsyncSeriesHook, 輸出文件到 output 目錄之前觸發(fā)
hook的類型總結(jié)(引用一張網(wǎng)上的圖片):
1.png

2、實(shí)際案例

clean-webpack-plugin 插件大部分人應(yīng)該用過斥难,可以在構(gòu)建項(xiàng)目時(shí)清理文件暑劝,下面來看一下 clean-webpack-plugin源碼

class CleanWebpackPlugin {
  // ...省略
  apply(compiler: Compiler) {
        if (!compiler.options.output || !compiler.options.output.path) {
            // eslint-disable-next-line no-console
            console.warn(
                'clean-webpack-plugin: options.output.path not defined. Plugin disabled...',
            );
            return;
        }
        this.outputPath = compiler.options.output.path;

        /**
         * webpack 4+ comes with a new plugin system.
         *
         * Check for hooks in-order to support old plugin system
         */
        const hooks = compiler.hooks;
        if (this.cleanOnceBeforeBuildPatterns.length !== 0) {
            if (hooks) {
                hooks.emit.tap('clean-webpack-plugin', (compilation) => {
                    this.handleInitial(compilation);
                });
            } else {
                compiler.plugin('emit', (compilation, callback) => {
                    try {
                        this.handleInitial(compilation);

                        callback();
                    } catch (error) {
                        callback(error);
                    }
                });
            }
        }
        // ...省略
    }
}

可以看到它使用到了 emit 這個(gè)hook该溯, 另外發(fā)現(xiàn) webpack4+ 和 老版本的webpack 編寫插件時(shí)的一些差異: 4+版本使用 compiler.hooks 老版本使用 compiler.plugin朗伶。
還有一些代碼沒有在這里展示猾漫,總體上刪除文件就是調(diào)用了del.sync悯周。

3锐墙、動(dòng)手編寫一個(gè)插件

下面按照webpack官網(wǎng)給的例子之拨,來實(shí)現(xiàn)一個(gè)插件听想,作用是在生成打包文件的目錄額外生成一個(gè)文件穴肘,記錄所有的打包文件。

test-webpack-plugin.js :

class TestWebpackPlugin {
  constructor(options) {
  }

  apply(compoiler) {
    compoiler.hooks.emit.tapAsync("TestWebpackPlugin", (compilation, cb) => {
     // 在生成文件中舔痕,創(chuàng)建一個(gè)頭部字符串:
    var filelist = "build files:\n\n";

    // compilation.assets 存放所有生成的文件信息
    for (var filename in compilation.assets) {
      filelist += ("- "+ filename + "\n");
    }

    /* 將這個(gè)列表作為一個(gè)新的文件資源评抚,插入到 webpack 構(gòu)建中: 
     * 文件內(nèi)容和文件長度需要通過source 和 size來定義
     */
    compilation.assets["filelist.md"] = {
      // 填充文件內(nèi)容
      source: function() {
        return filelist;
      },
      // 文件長度
      size: function() {
        return filelist.length;
      }
    };
    cb();
    })
  }
}

module.exports = TestWebpackPlugin

webpack.config.js:

const path = require("path")
const TestWebpackPlugin = require("./plugins/test-webpack-plugin")

module.exports = {
    mode: "development",
    entry: {
        main: "./src/index.js"
    },
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "[name].[hash].js"
    },
    plugins: [
        new TestWebpackPlugin({ name: "測試參數(shù)"}) 
    ]
}

打包后dist目錄多了一個(gè)文件:


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市伯复,隨后出現(xiàn)的幾起案子慨代,更是在濱河造成了極大的恐慌,老刑警劉巖啸如,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侍匙,死亡現(xiàn)場離奇詭異,居然都是意外死亡叮雳,警方通過查閱死者的電腦和手機(jī)想暗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帘不,“玉大人说莫,你說我怎么就攤上這事⊙峋” “怎么了唬滑?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵告唆,是天一觀的道長棺弊。 經(jīng)常有香客問我,道長擒悬,這世上最難降的妖魔是什么模她? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮懂牧,結(jié)果婚禮上侈净,老公的妹妹穿的比我還像新娘。我一直安慰自己僧凤,他們只是感情好畜侦,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著躯保,像睡著了一般旋膳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上途事,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天验懊,我揣著相機(jī)與錄音擅羞,去河邊找鬼。 笑死义图,一個(gè)胖子當(dāng)著我的面吹牛减俏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播碱工,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼娃承,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了怕篷?” 一聲冷哼從身側(cè)響起草慧,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎匙头,沒想到半個(gè)月后漫谷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹂析,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年舔示,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片电抚。...
    茶點(diǎn)故事閱讀 40,680評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惕稻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蝙叛,到底是詐尸還是另有隱情俺祠,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布借帘,位于F島的核電站蜘渣,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏肺然。R本人自食惡果不足惜蔫缸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望际起。 院中可真熱鬧拾碌,春花似錦、人聲如沸街望。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灾前。三九已至防症,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背告希。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工扑浸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人燕偶。 一個(gè)月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓喝噪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親指么。 傳聞我的和親對象是個(gè)殘疾皇子酝惧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 前言 Plugin(插件) 是 webpack 生態(tài)的的一個(gè)關(guān)鍵部分。它為社區(qū)提供了一種強(qiáng)大的方法來擴(kuò)展 webp...
    champyin閱讀 1,882評論 0 3
  • 編寫一個(gè)webpack plugin(基礎(chǔ)篇) 創(chuàng)建插件 webpack插件由以下組成 一個(gè)具名javaScrip...
    拋荒了四序閱讀 2,533評論 4 58
  • 作為先進(jìn)最為流行的前端構(gòu)建工具之一伯诬,webpack成為了前端開發(fā)必須掌握的技能晚唇。其諸多的插件為我們的工作帶來了大大...
    緋色流火閱讀 4,354評論 0 13
  • 編寫 Loader Loader就像是一個(gè)翻譯員,能把源文件經(jīng)過轉(zhuǎn)化后輸出新的結(jié)果盗似,并且一個(gè)文件還可以鏈?zhǔn)降慕?jīng)過多...
    oWSQo閱讀 7,599評論 0 8
  • 前幾篇文章中哩陕,我們介紹了webpack v4.20.2相關(guān)的內(nèi)容,但是很多老項(xiàng)目赫舒,還在使用webpack 3悍及,也要...
    何幻閱讀 2,675評論 0 1