Webpack 插件機(jī)制的目的是為了增強(qiáng) Webpack 在項(xiàng)目自動(dòng)化構(gòu)建方面的能力。
上一節(jié)邑茄,Loader負(fù)責(zé)完成項(xiàng)目中各樣資源的加載姨蝴,從而實(shí)現(xiàn)項(xiàng)目整體模塊化。
這一節(jié)肺缕,Plugin能力更廣左医,負(fù)責(zé)解決除了資源模塊打包外的其他自動(dòng)化工作授帕;
我在這里先介紹幾個(gè)插件最常見(jiàn)的應(yīng)用場(chǎng)景:
- 實(shí)現(xiàn)自動(dòng)在打包之前清除 dist 目錄(上次的打包結(jié)果);
- 自動(dòng)生成應(yīng)用所需要的 HTML 文件浮梢;
- 根據(jù)不同環(huán)境為代碼注入類似 API 地址這種可能變化的部分跛十;
- 拷貝不需要參與打包的資源文件到輸出目錄;
- 壓縮 Webpack 打包完成后輸出的文件秕硝;
- 自動(dòng)發(fā)布打包結(jié)果到服務(wù)器實(shí)現(xiàn)自動(dòng)部署芥映。
總之,有了Plugin远豺,Webpack幾乎’無(wú)所不能’奈偏,借助插件我們可以輕松實(shí)現(xiàn)前端工程化中的絕大多數(shù)功能,使得很多初學(xué)者把Webpack和前端工程化混淆憋飞;
接下來(lái)計(jì)劃先通過(guò)一些常用插件的使用霎苗,了解Plugin機(jī)制,
再通過(guò)自己開(kāi)發(fā)一個(gè)插件榛做,理解Plugin原理唁盏;
常用插件:
1、clean-webpack-plugin检眯,自動(dòng)清除輸出目錄的插件
通過(guò)之前的嘗試厘擂,我們發(fā)現(xiàn)webpack每次打包的結(jié)果就是直接覆蓋到dist目錄。但dist目錄中可能存在一些在上次打包操作時(shí)遺留的文件锰瘸,此時(shí)會(huì)出現(xiàn)一些已經(jīng)移除的文件還冗余其中的情況刽严,最終導(dǎo)致線上部署的時(shí)候出現(xiàn)多余文件,這顯然很不合理避凝;
更合理的做法就是舞萄,每次打包前清理一遍dist目錄,保證實(shí)時(shí)性管削,每次都是最新的倒脓;
clean-webpack-plugin插件就實(shí)現(xiàn)了這個(gè)需求,它是個(gè)第三方npm包含思,用前需要安裝下:
$ npm install clean-webpack-plugin --save-dev
此時(shí)執(zhí)行打包之后崎弃,dist文件會(huì)被清空,然后重新生成打包文件含潘;
P.S. 報(bào)錯(cuò):如果output不配置path的話饲做,會(huì)報(bào)錯(cuò)clean-webpack-plugin: options.output.path not defined. Plugin disabled...
解決:在output中聲明path屬性如下圖,或者選擇clean屬性配置(webpack新版本的替代解決方案)
webpack 5.20.0升級(jí)后遏弱,output.clean選項(xiàng)可以再打包之前清理輸出目錄盆均;已經(jīng)替代了這個(gè)插件的作用
2、 html-webpack-plugin漱逸,用于生成 HTML 的插件
首先泪姨,我們要知道html文件居砖,一般都是通過(guò)硬編碼的方式,單獨(dú)存放在項(xiàng)目根目錄中驴娃。此時(shí)會(huì)有問(wèn)題:項(xiàng)目發(fā)布時(shí),我們同時(shí)要發(fā)布根目錄下的html+dist里的所有打包文件循集,還要確保上線后html代碼中的資源文件路徑正確唇敞,非常麻煩;如果打包結(jié)果輸出的目錄或者文件名發(fā)生變化咒彤,html代碼中所對(duì)應(yīng)的script標(biāo)簽也需要我們手動(dòng)修改疆柔;
解決這個(gè)問(wèn)題最好的辦法就是讓webpack在打包的同時(shí),自動(dòng)生成對(duì)應(yīng)的html文件镶柱,讓webpack將打包的bundle文件自動(dòng)引入頁(yè)面中旷档;此時(shí)需要html-webpack-plugin
$ npm install html-webpack-plugin --save-dev
安裝后,返回配置文件歇拆。引入并在plugin屬性中添加這個(gè)類型的實(shí)例對(duì)象鞋屈,完成插件使用;
此時(shí)打包后厂庇,會(huì)在dist中自動(dòng)生成一個(gè)使用了bundle.js的空白html文件
至此,webpack可以動(dòng)態(tài)生成應(yīng)用所需的html文件了输吏,但是仍需要有些改動(dòng)的地方:
對(duì)于生成的html文件权旷,頁(yè)面title必須要改;
還需要自定義頁(yè)面的meta標(biāo)簽和一些基礎(chǔ)的DOM結(jié)構(gòu)
即少量修改靠配置項(xiàng)贯溅,大量修改靠模版
簡(jiǎn)單的修改拄氯,通過(guò)在HtmlWebpackPlugin對(duì)象中修改參數(shù):
如果是大量的自定義,最好的做法是在源代碼中添加一個(gè)用于生成html的模版它浅,然后讓這個(gè)插件根據(jù)模版去生成頁(yè)面;
在src文件夾下新建一個(gè)html文件译柏,然后根據(jù)我們的需要在這個(gè)文件中添加相應(yīng)的元素。對(duì)于模板中動(dòng)態(tài)的內(nèi)容罚缕,可以使用 Lodash 模板語(yǔ)法輸出艇纺,模板中可以通過(guò) htmlWebpackPlugin.options 訪問(wèn)這個(gè)插件的配置數(shù)據(jù),例如我們這里輸出配置中的 title 屬性邮弹,具體代碼如下:
有了模版文件之后黔衡,在webpack.config.js里修改對(duì)應(yīng)配置屬性
此時(shí)再打包文件腌乡,生成的html就是根據(jù)模版內(nèi)容產(chǎn)生的文件了
關(guān)于 html-webpack-plugin 插件盟劫,除了自定義輸出文件的內(nèi)容,同時(shí)輸出多個(gè) HTML 文件也是一個(gè)非常常見(jiàn)的需求与纽,除非我們的應(yīng)用是一個(gè)單頁(yè)應(yīng)用程序侣签,否則一定需要輸出多個(gè) HTML 文件塘装。
如果需要同時(shí)輸出多個(gè) HTML 文件,其實(shí)也非常簡(jiǎn)單影所,我們回到配置文件中蹦肴,這里通過(guò) HtmlWebpackPlugin 創(chuàng)建的對(duì)象就是用于生成 index.html 的,那我們完全可以再創(chuàng)建一個(gè)新的實(shí)例對(duì)象猴娩,用于創(chuàng)建額外的 HTML 文件阴幌。
例如,這里我們?cè)賮?lái)添加一個(gè) HtmlWebpackPlugin 實(shí)例用于創(chuàng)建一個(gè) about.html 的頁(yè)面文件卷中,我們需要通過(guò) filename 指定輸出文件名矛双,這個(gè)屬性的默認(rèn)值是 index.html,我們把它設(shè)置為 about.html蟆豫,具體配置如下:
完成以后我們?cè)俅位氐矫钚薪K端,運(yùn)行打包命令十减,然后我們展開(kāi) dist 目錄栈幸,此時(shí) dist 目錄中就同時(shí)生成了 index.html 和 about.html 兩個(gè)頁(yè)面文件。
根據(jù)這個(gè)嘗試我們就應(yīng)該知道帮辟,如果需要?jiǎng)?chuàng)建多個(gè)頁(yè)面侦镇,就需要在插件列表中加入多個(gè) HtmlWebpackPlugin 的實(shí)例對(duì)象,讓每個(gè)對(duì)象負(fù)責(zé)一個(gè)頁(yè)面文件的生成织阅。
下一節(jié)壳繁,我們手寫(xiě)一個(gè)Loader加載器和Plugin插件