当前位置: 首页 > Web前端 > HTML

webpack实战,手写loader和plugin

时间:2023-03-29 13:15:51 HTML

鍓嶈█瀵逛簬webpack鏉ヨ锛宭oader鍜宲lugin鍙互璇存槸闇€姹傛渶骞挎硾鐨勯厤缃」浜嗐€備絾鏄紝浠呴厤缃彲鑳借繕涓嶅銆傚鏋滄垜浠湁鏃跺€欐兂DIY涓€涓渶姹傦紝浣嗘槸webpack娌℃湁鐩稿叧鐨刲oader鍜宲lugin銆傝繖涓椂鍊欐垜浠彲鑳借寮€濮嬮€犱竴浜涜疆瀛愮粰鑷繁鐢ㄤ簡銆傚洜姝わ紝鍦ㄤ粖澶╃殑鏂囩珷涓紝鎴戝皢甯﹂澶у鎵嬪啓涓€涓畝鍗曠殑loader鍜宲lugin锛屽涔犲浣曞湪椤圭洰涓娇鐢ㄨ嚜宸辩紪鍐欑殑loader鍜宲lugin銆備竴璧锋潵瀛︿範鍚馃摙1.濡備綍鍐欎竴涓狶oader1銆傚湪涓婁竴绡囨枃绔犱腑锛屾垜浠皥鍒颁簡涓€浜涘姞杞藉櫒閰嶇疆銆傞偅涔堝鏋滄妸閭d簺寮曠敤鐨刲oader鏀规垚鎴戜滑鍐欑殑loader鎬庝箞鍔炲憿锛熺幇鍦紝璁╂垜浠湅鐪嬪浣曟墜鍔ㄧ紪鍐欎竴涓畝鍗曠殑鍔犺浇鍣ㄥ苟灏嗗叾搴旂敤鍒版垜浠殑椤圭洰涓€?.椤圭洰缁撴瀯棣栧厛鐢ㄤ竴寮犲浘鏉ョ湅涓€涓嬫垜浠殑椤圭洰缁撴瀯銆傚涓嬪浘鎵€绀猴細鎴戜滑瑕佺紪鍐欑殑loader鏀惧湪loaders鏂囦欢澶逛笅锛岄噷闈㈢殑replaceLoader.js鏂囦欢鍖呭惈浜嗘垜浠嵆灏嗙紪鍐欑殑loader鐨勪唬鐮侀€昏緫銆備箣鍚巌ndex.js鏂囦欢灏辨槸鎴戜滑鐨勫叆鍙f枃浠讹紝鎴戜滑鏀剧疆涓氬姟閫昏緫鐨勫湴鏂广€倃ebpack.config.js鏂囦欢鏀剧疆浜唚ebpack鐨勭浉鍏抽厤缃紝dist鏂囦欢澶逛腑鐨勫唴瀹规槸鎴戜滑閫氳繃webpack鎵撳寘鍚庣敓鎴愮殑鎵撳寘鏂囦欢銆?.涓氬姟浠g爜缂栧啓(1)鍏ュ彛鏂囦欢浠g爜涓嬮潰鎴戜滑鍏堟潵缂栧啓鍏ュ彛鏂囦欢index.js鐨勪唬鐮併€傚叿浣撲唬鐮佸涓嬶細console.log('hellomonday');(2)鍔犺浇鍣ㄥ叆鍙f枃浠剁殑鍐呭鍐欒捣鏉ュ緢绠€鍗曘€傛垜浠瀹炵幇鐨勬槸杈撳嚭璇彞hellomonday銆傜幇鍦紝鎴戜滑鏉ュ啓loader鐨勫唴瀹癸紝灏卞埌浜嗕慨鏀瑰叆鍙f枃浠秈ndex.js鍐呭鐨勫湴姝ヤ簡銆俽eplaceLoader.js鏂囦欢鐨勪唬鐮佸涓嬶細module.exports=function(source){constresult=source.replace('monday','mondaylab');this.callback(null,result);}涓婇潰浠g爜鐨勬剰鎬濇槸锛屽皢鍏ュ彛鏂囦欢index.js涓殑monday鏇挎崲涓簃ondaylab銆傝繖鏍峰啓濂藉儚娌′粈涔堥棶棰橈紝浣嗘槸澶у鏈夋病鏈夋兂杩囷紝鏈夋椂鍊欐垜浠紶閫掔殑灞炴€у彲鑳戒細寰堝鎬紝涓嶄竴瀹氭瘡娆¢兘杩欐牱鐢ㄥ瓧绗︿覆鐨勫舰寮忔潵鏇挎崲銆傚洜姝わ紝鎴戜滑鍙傝€僿ebpack瀹樻柟鎺ㄨ崘鐨刲oadertils宸ュ叿鏉ヨВ鍐宠繖涓棶棰樸€傜1姝ワ細瀹夎loader-utils鎻掍欢銆傚叿浣撳懡浠ゅ涓嬶細npminstallloader-utils--save-dev绗簩姝ワ細杞崲loader鏂囦欢銆傛帴涓嬫潵鎴戜滑鍗囩骇replaceLoader.js鏂囦欢锛屽叿浣撲唬鐮佸涓嬶細constloaderUtils=require('loader-utils');//涔嬫墍浠ヤ娇鐢╢unction鏄负浜嗕笟鍔″眰璋冪敤杩欎釜//source鏄鍏ユ枃浠剁殑婧愪唬鐮乵odule.exports=function(source){//getOptions浼氳嚜鍔ㄥ府鎴戜滑瑙f瀽this.query锛岀劧鍚庢妸鍙傛暟鐨勬墍鏈夊唴瀹规斁鍒皁ptions涓璫onstoptions=loaderUtils.getOptions(this);constresult=source.replace('monday',options.name);this.callback(null,result);}鍙互鐪嬪埌锛岄€氳繃浣跨敤loaderUtils鎻掍欢锛岄棿鎺ヨ皟鐢╣etOptions鏂规硶鑷姩甯垜浠В鏋恡his.query锛屼粠鑰屽緱鍒版垜浠兂瑕佺殑鍐呭銆傚€煎緱娉ㄦ剰鐨勬槸锛屾垜浠繕闇€瑕佷簡瑙d竴涓媡his.callback鐨勫唴瀹广€備竴鑸儏鍐典笅锛屽鏋滄垜浠凡缁忔敹鍒版簮鐮乻ource锛岄偅涔堢幇鍦ㄥ彧鑳藉婧愮爜杩涜澶勭悊浜嗐€備絾鏄紝鏈夋椂鍊欙紝鎴戜滑鎯充娇鐢ㄤ竴浜泂ourceMap锛屾垨鑰呭垎鏋愬畬婧愮爜鍚庯紝鎴戜滑涓嶄粎瑕佽繑鍥炴簮鐮侊紝杩樿鎶妔ourceMap甯﹀洖鏉ャ€傚洜涓烘垜浠繑鍥炵殑鏃跺€欏彧鑳借繑鍥炰竴涓弬鏁帮紝鍏朵綑澶氫綑鐨勫唴瀹规槸甯︿笉鍑烘潵鐨勩€傝繖鏃跺€欏氨闇€瑕乼his.callback鏉ュ府鎴戜滑甯﹀嚭sourceMap浜嗐€傛墍浠ワ紝涓€鑸娇鐢╰his.callback鏉ヨ繑鍥炲唴瀹广€?3)寮曠敤loader鐜板湪锛屾垜浠湪webpack.config.js涓紝鏉ヤ粙缁嶆垜浠笂闈㈢殑loader銆傚叿浣撻厤缃涓嬶細constpath=require('path');module.exports={mode:'development',entry:{main:'./src/index.js'},module:{rules:[{test:/\.js/,use:[{loader:path.resolve(__dirname,'./loaders/replaceLoader.js'),//nameinoptions.name涓婇潰options:{name:'mondaylab'}}]}]},output:{path:path.resolve(__dirname,'dist'),filename:'[name].js'}}閫氳繃涓婇潰鐨勬柟娉曪紝鎴戜滑鍐欎簡涓€涓畝鍗曠殑loader锛屽疄鐜颁簡鏇挎崲monday涓簃ondaylab鐨勪竴涓嚱鏁般€傚苟涓旇鎴戜滑鍦╳ebpack涓娇鐢ㄦ垜浠嚜宸辩殑鍔犺浇鍣ㄣ€?4)鍦╨oader涓仛涓€浜涘紓姝ユ搷浣溿€傜幇鍦紝濡傛灉鎴戜滑鎯冲鍔犺浇鍣ㄨ繘琛屼竴浜涘紓姝ユ搷浣滐紝鎴戜滑璇ュ浣曞疄鐜板憿锛熶负鎴戜滑缂栧啓鐨勫姞杞藉櫒娣诲姞寮傛鎿嶄綔锛岄渶瑕佽皟鐢ㄥ畼鏂规彁渚涚粰鎴戜滑鐨則his.async()API鏉ュ疄鐜般€傜幇鍦紝璁╂垜浠慨鏀箁eplaceLoader.js鏂囦欢鐨勪唬鐮併€傚叿浣撲唬鐮佸涓嬶細constloaderUtils=require('loader-utils');module.exports=function(source){constoptions=loaderUtils.getOptions(this);//璋冪敤this.async()API缁欏嚭寮傛浠g爜Useconstcallback=this.async();setTimeout(()=>{constresult=source.replace('monday',options.name);callback(null,result);},1000);}杩欐牱鎴戜滑灏卞彲浠ュ湪loader涓啓寮傛浠g爜鏉ュ疄鐜版垜浠兂瑕佺殑鏁堟灉銆?5)loader璺緞鑷畾涔夋湁涓皬娉ㄦ剰鐐广€傛垜浠湪webpack.config.js鏂囦欢涓厤缃甽oader鐨勮矾寰勬椂锛屾瘡娆¢兘闇€瑕乸ath.resolve鏉ユ煡鎵捐矾寰勬枃浠躲€傛枃浠跺皯鐨勬椂鍊欒繕濂斤紝鏂囦欢澶氫簡鎬庝箞鍔烇紵浼氫笉浼氬緢楹荤儲銆傛墍浠ワ紝鎴戜滑鍙傝€價esolveLoader鏉ョ畝鍖栧畠銆傜幇鍦ㄦ垜浠湪webpack.config.js鏂囦欢涓繘琛屾敼閫犮€傚叿浣撻厤缃涓嬶細constpath=require('path');module.exports={//鍏堝幓node_modules閲屾壘锛屽鏋滄壘涓嶅埌鍐嶅幓./loaders鐩綍閲屾壘resolveLoader:{modules:['node_modules','./loaders']},module:{rules:[{test:/\.js/,use:[{loader:'replaceLoader'}]}]}}鍙傝€冨墠绔珮绾ч潰璇曢鐨勮缁嗙瓟妗堬紝閰嶇疆resolveLoader鏉ユ墽琛宭ookup鍦ㄦ枃浠剁洰褰曚笂锛岀畝鍖栦簡璺緞鍐呭銆備簩銆佸浣曞啓涓€涓狿lugin1.宀佸瞾鍦ㄨ瑙f彃浠朵箣鍓嶏紝鍏堜簡瑙d竴涓媗oader鍜宲lugin鐨勫尯鍒€傚綋鎴戜滑鍦ㄦ簮鐮佷腑寮曞叆涓€涓柊鐨刯s鏂囦欢鎴栬€呭叾浠栨牸寮忕殑鏂囦欢鏃讹紝鎴戜滑鍙互浣跨敤loader鏉ュ府鍔╂垜浠鐞嗘垜浠紩鐢ㄧ殑loader鏂囦欢銆俵oader鐨勪綔鐢ㄥ氨鏄府鍔╂垜浠鐞嗗紩鐢ㄧ殑妯″潡銆傝嚦浜庢彃浠讹紝鎴戜滑鍦ㄦ墦鍖呯殑鏃跺€欙紝鍦ㄦ煇浜涚壒瀹氱殑鏃跺埢锛屾瘮濡傛垜浠墦鍖呬箣鍚庯紝鎴戜滑瑕佺敓鎴愪竴涓猦tml鏂囦欢銆傝繖鏃跺€欐垜浠彲浠ヤ娇鐢╤tmlWebpackPlugin杩欎釜鎻掍欢銆備娇鐢ㄥ悗浠栦細鍦ㄦ墦鍖呭畬鎴愬悗甯垜浠敓鎴愬搴旂殑html鏂囦欢銆傚啀姣斿锛屾垜浠渶瑕佸湪鎵撳寘鍓嶆竻绌篸ist鐩綍銆傝繖鏃跺€欐垜浠氨鍙互浣跨敤cleanWebpackPlugin鏉ュ府鎴戜滑鍋氳繖浠朵簨銆傞偅涔堬紝鎻掍欢浠€涔堟椂鍊欑敓鏁堝憿锛熷湪鎴戜滑鎵撳寘杩囩▼鐨勬煇涓椂鍒伙紝灏辨槸鎻掍欢鐢熸晥鐨勫満鏅€俻lugin鐨勫啓娉曚細姣攍oader闅句竴鐐广€備絾鏄紝濡傛灉浣犵湅杩噖ebpack鐨勬簮鐮侊紝浣犲彲鑳界煡閬搘ebpack鐨勪竴浜涘簳灞傚師鐞嗘槸鍩轰簬plugin缂栧啓鐨勩€傛墍浠ワ紝鎴戜滑杩樻槸鏈夊繀瑕佸涔犱竴涓嬫彃浠剁紪鍐欑殑銆備笅闈㈠皢甯﹂澶у鍐欎竴涓畝鍗曠殑鎻掍欢~2銆傞」鐩粨鏋勫浜巜ebpack鐨刾lugin鏉ヨ锛屾槸鍩轰簬鍙戝竷鑰呰闃呯殑璁捐妯″紡锛屼篃鍙互璇存槸鍩轰簬浜嬩欢椹卞姩鏉ュ疄鐜扮殑銆傚湪杩欑浜嬩欢椹卞姩涓紝浠g爜鐨勬墽琛屾槸鐢变簨浠堕┍鍔ㄧ殑銆傛帴涓嬫潵锛岃鎴戜滑缂栧啓涓€涓畝鍗曠殑鎻掍欢銆傞鍏堢敤涓€寮犲浘鏉ョ湅涓€涓嬫垜浠殑椤圭洰缁撴瀯銆傚涓嬪浘鎵€绀猴細鎴戜滑瑕佸啓鐨勬彃浠舵斁鍦╬lugins鏂囦欢澶逛笅锛岄噷闈㈢殑copyright-webpack-plugin.js鏂囦欢鍖呭惈浜嗘垜浠鍐欑殑鎻掍欢鐨勪唬鐮侀€昏緫銆備箣鍚巌ndex.js鏂囦欢灏辨槸鎴戜滑鐨勫叆鍙f枃浠讹紝鎴戜滑鏀剧疆涓氬姟閫昏緫鐨勫湴鏂广€倃ebpack.config.js鏂囦欢鏀剧疆浜唚ebpack鐨勭浉鍏抽厤缃紝dist鏂囦欢澶逛腑鐨勫唴瀹规槸鎴戜滑閫氳繃webpack鎵撳寘鍚庣敓鎴愮殑鎵撳寘鏂囦欢銆?.涓氬姟浠g爜缂栧啓(1)鍏ュ彛鏂囦欢浠g爜涓嬮潰鎴戜滑鍏堟潵缂栧啓鍏ュ彛鏂囦欢index.js鐨勪唬鐮併€傚叿浣撲唬鐮佸涓嬶細console.log('hellomonday');(2)缂栧啓鎻掍欢鐜板湪锛屾垜浠潵缂栧啓鎻掍欢鐨勫唴瀹广€俢opyright-webpack-plugin.js鏂囦欢鐨勪唬鐮佸涓嬶細compile.tap('CopyrightWebpackPlugin',()=>{console.log('compiler');});//寮傛鏃跺埢//鎯虫妸浠g爜鏀惧埌dist鐩綍涓嬬殑鏃跺€欙紝闇€瑕佸埌涓嬮潰杩欎釜鍑芥暟//Compilation瀛樻斁鎵€鏈夋墦鍖呯殑鍐呭锛孋ompilation.assets鏀剧疆鐢熸垚鐨勫唴瀹筩ompiler.hooks.emit.tapAsync('CopyrightWebpackPlugin',(Compilation,cb)=>{debugger;//鍦ㄤ唬鐮佷腑娣诲姞涓€涓枃浠讹紝copyright.txtCompilation.assets['copyright.txt']={source:function(){return'copyrightbymonday';},澶у皬:function(){return19;}};cb();})}}module.exports=CopyrightWebpackPlugin;涓婇潰鎻掍欢瑕佸疄鐜扮殑鍔熻兘鏄幏鍙栫増鏈巿鏉冧俊鎭?3)寮曠敤鎻掍欢鐜板湪锛屾垜浠湪webpack.config.js涓紝浠嬬粛涓€涓嬫垜浠笂闈㈢殑鎻掍欢銆傚叿浣撻厤缃涓嬶細constpath=require('path');constCopyrightWebpackPlugin=require('./plugins/copyright-webpack-plugin');module.exports={mode:'development',entry:{main:'./src/index.js'},鎻掍欢:[newCopyrightWebpackPlugin({name:'monday'})],杈撳嚭:{path:path.resolve(__dirname,'dist'),鏂囦欢鍚?'[name].js'}}閫氳繃涓婇潰鐨勪唬鐮侊紝鎴戜滑鍙互浜嗚В鍒帮紝鍦紙2锛変腑锛屾垜浠鍏堥渶瑕佸畾涔変竴涓被锛岀劧鍚庡湪绫讳腑鍐欎竴涓瀯閫犲嚱鏁板拰涓€涓猘pply()鏂规硶鏉ヨ皟鐢ㄣ€傜劧鍚庯紝鍙互鐪嬪埌锛?锛夛紝浣跨敤require鏂规硶鏂板缓涓€涓疄渚嬶紝瀹炰緥鍖栦竴涓彃浠讹紝鍦ㄩ」鐩腑浣跨敤杩欎釜鎻掍欢銆傛渶鍚庢垜浠殑椤圭洰鎵撳寘鐨勬椂鍊欎細鐢熸垚涓€涓猟ist鐩綍锛岀洰褰曚笅浼氬鍔犱竴涓猚opyright.txt鏂囦欢锛屾枃浠朵腑鐨勫唴瀹规槸copyrightbymonday銆?.缁撴潫璇湪涓婇潰鐨勬枃绔犱腑锛屾垜璁茶В浜唋oader鍜宲lugin鐨勫熀鏈紪鍐欐€濊矾锛屼互鍙婂浣曞湪椤圭洰涓娇鐢ㄣ€傜浉淇″ぇ瀹跺杩欎釜鍐呭閮芥湁浜嗗熀鏈殑浜嗚В銆傝嚦姝わ紝loader鍜宲lugin鐨勭紪鍐欒瑙e氨缁撴潫浜嗭紒甯屾湜瀵瑰ぇ瀹舵湁鎵€甯姪~