<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          剛剛,發(fā)布Webpack中級教程系列

          共 5474字,需瀏覽 11分鐘

           ·

          2021-08-15 14:51



          webpack是什么?


          webpack是前端最火的打包工具,是大前端自動(dòng)化工廠的重要組成部分。


          webpack關(guān)于HTML的部分


          對于瀏覽器而言,html文件是用戶訪問的入口點(diǎn),也是所有資源的掛載點(diǎn),所有資源都是通過html中的標(biāo)記來進(jìn)行引用的。

          webpack的構(gòu)建世界里,html只是一個(gè)展示板,而entry參數(shù)中指定的javascript入口文件才是真正在構(gòu)建過程中管理和調(diào)度資源的掛載點(diǎn),html文件中最終展示的內(nèi)容,都是webpack在加工并為所有資源打好標(biāo)記以后傳遞給它的,業(yè)界將這種有別與瀏覽器的模式稱之為“webpack的逆向注入”

          前端項(xiàng)目可以大致分為 單頁面應(yīng)用 和 多頁面應(yīng)用

          html文件主要作為訪問入口文件,是<style> 樣式標(biāo)簽和<script>腳本標(biāo)簽的掛載點(diǎn)


          打包中需要注意:


          - 第一,個(gè)性化內(nèi)容填充,如頁面標(biāo)題,描述,關(guān)鍵字;

          - 第二,多余空格刪除,連續(xù)多個(gè)空白字符的合并;

          - 第三,代碼壓縮,多余空白字符的合并;

          - 第四,去除注解


          入口html文件的處理


          - 單頁面應(yīng)用打包


          入口html文件的處理使用 html-webpack-plugin 插件來設(shè)置一定的配置參數(shù)。


          webpack.config.js配置



          index.html 模板文件(構(gòu)建生成的入口頁面是以此為模板的):



          多頁面應(yīng)用打包


          項(xiàng)目中有多個(gè)頁面,考慮兩個(gè)基本問題:


          - 如何自動(dòng)生成多個(gè)頁面

          - 如果引用中存在公共的模塊,怎么樣才能提取公共模塊


          多頁面應(yīng)用的基本結(jié)構(gòu)理解起來并不復(fù)雜,可以將其看做是多個(gè)單頁面應(yīng)用的組合


          entry參數(shù)需要配置多個(gè)依賴入口文件



          html文件則需要分別引用對應(yīng)的入口文件并生成對應(yīng)的訪問入口:



          可以看到在生成html文件時(shí)已經(jīng)為其單獨(dú)引用了chunks數(shù)組中指定的模塊,這使得對應(yīng)的頁面生成時(shí)只依賴自己需要的腳本。


          html-webpack-plugin插件是依賴于html-loader而工作的,當(dāng)你顯式使用/\.html$/作為規(guī)則來篩選文件時(shí),同樣會(huì)選擇到作為入口文件的html資源,從而造成沖突報(bào)錯(cuò)。


          webpack中關(guān)于CSS的部分


          CSS文件的處理,需要處理的基本問題:


          - 預(yù)編譯語言轉(zhuǎn)換

          - 樣式文件掛載方式選擇

          - 代碼優(yōu)化(合并以及壓縮)

          - 去除或保留指定格式的注解

          - 資源定位路徑的轉(zhuǎn)換

          - 響應(yīng)式布局單位轉(zhuǎn)換

          - 模塊化

          - 處理瀏覽器兼容


          > 解決方案


          舊的解決方案預(yù)編譯語言 + 命名方法論

          新的解決方案預(yù)編譯語言 + 構(gòu)建工具 + BEM + ACSS全局樣式+CSSModule組件樣式POSTCSS


          舊:例如編寫簡單的@mixin px2rem( )函數(shù)來將開發(fā)中使用的px單位轉(zhuǎn)換為rem單位,達(dá)到移動(dòng)端自適應(yīng)的目的,或是編寫一些處理兼容性的函數(shù)來處理瀏覽器兼容性。


          新:構(gòu)建工具可以通過自動(dòng)化檢測將預(yù)編譯語言轉(zhuǎn)換為CSS,基于現(xiàn)代化構(gòu)建工具的CSS-Module功能,可以通過特定的語法解決CSS模塊化的問題,而基于POSTCSS實(shí)現(xiàn)的autoprefixer插件,可以依據(jù)CanIUse網(wǎng)站提供的瀏覽器支持度數(shù)據(jù)實(shí)現(xiàn)代碼的跨瀏覽器前綴自動(dòng)補(bǔ)齊。


          常用的插件:


          - style-loader——將處理結(jié)束的CSS代碼存儲(chǔ)在js中,運(yùn)行時(shí)嵌入<style>后掛載至html頁面上

          - css-loader——加載器,使webpack可以識(shí)別css模塊

          - postcss-loader——加載器

          - sass-loader——加載器,使webpack可以識(shí)別scss/sass文件,默認(rèn)使用node-sass進(jìn)行編譯

          - mini-css-extract-plugin——插件,4.0版本啟用的插件,替代原extract-text-webpack-plugin插件,將處理后的CSS代碼提取為獨(dú)立的CSS文件

          - optimize-css-assets-webpack-plugin——插件,實(shí)現(xiàn)CSS代碼壓縮

          - autoprefixer——自動(dòng)化添加跨瀏覽器兼容前綴


          使用SCSS作為預(yù)編譯語言





          可以看到轉(zhuǎn)換后的結(jié)果:



          代碼壓縮等優(yōu)化功能在 默認(rèn)當(dāng)mode: 'production'時(shí)有效


          使用CSS-Modules


          CSS Module在CSS中使用類選擇器,其基本原理是將CSS代碼中的樣式名替換為哈希值,并建立一個(gè)json對照表,在js文件中對于屬性名選擇器的使用均被替換為哈希字符串,以此來解決CSS模塊化的問題。


          在webpack中使用CSS Modules功能非常簡單,只需要在css-loader的配置參數(shù)中設(shè)置:{modules:true}即可激活模塊化功能。

          開啟模塊化功能后再進(jìn)行打包,可以看到同樣的main.css文件變成了如下樣子:



          進(jìn)一步了解 Css-Process-Chain


          webpack中關(guān)于Assets部分


          Assets資源的基本處理需求

          Assets,指項(xiàng)目中被引用的資源,通常為各種格式的圖片和字體文件,當(dāng)然也可能包含各式各樣其他擴(kuò)展名的文件(.json,.xml等),常見的圖片和文字資源的處理包括:


          - 體積壓縮

          - 雪碧圖合并及引用修正

          - 資源的引用路徑自動(dòng)替換


          webpack處理引用資源


          資源打標(biāo)

          webpack通過file-loader處理資源文件,它會(huì)將rules規(guī)則命中的資源文件按照配置的信息(路徑,名稱等)輸出到指定目錄,并返回其資源定位地址(輸出路徑,用于生產(chǎn)環(huán)境的publicPath路徑),默認(rèn)的輸出名是以原文件內(nèi)容計(jì)算的MD5 Hash命名的。



          引用優(yōu)化

          構(gòu)建工具通過url-loader來優(yōu)化項(xiàng)目中對于資源的引用路徑,并設(shè)定大小限制,當(dāng)資源的體積小于limit時(shí)將其直接進(jìn)行Base64轉(zhuǎn)換后嵌入引用文件,體積大于limit時(shí)可通過fallback參數(shù)指定的loader進(jìn)行處理。



          sprites雪碧圖合成

          雪碧圖合成,聽起來是一個(gè)顯得略高端的知識(shí)點(diǎn),但它并不是必須進(jìn)行的,任何一種技術(shù)都有其使用場景。有的場景下需要將圖片資源合并為獨(dú)立的雪碧圖而減少http請求的次數(shù),有的時(shí)候或許通過url-loader直接將其嵌入文檔就可以。矢量圖在不同場景下的處理方式也不相同。


          采用url-loader + file-loader作為資源處理的一般通用方案


          位圖處理




          矢量圖處理


          開發(fā)中常用的矢量圖為svg格式,既可以使用inline-svg-loader進(jìn)行資源嵌入,也可以使用svg-sprite-loader將矢量圖資源合并為雪碧圖,具體采用哪種方案,需要由項(xiàng)目的實(shí)際情況來判斷。



          圖片壓縮


          圖片資源是可以以清晰度為量化參考進(jìn)行體積壓縮的?


          webpack中關(guān)于JavaScript和splitChunk


          javascript之所以需要打包合并,是因?yàn)槟K化開發(fā)的存在。開發(fā)階段我們需要將js文件分開寫在很多零碎的文件中,方便調(diào)試和修改,但如果就這樣上線,那首頁的http請求數(shù)量將直接爆炸。同一個(gè)項(xiàng)目,別人2-3個(gè)請求就拿到了需要的文件,而你的可能需要20-30個(gè),結(jié)果就不用多說了。


          但是合并腳本可不是“把所有的碎片文件都拷貝到一個(gè)js文件里”這樣就能解決的,不僅要解決命名空間沖突的問題,還需要兼容不同的模塊化方案,更別提根據(jù)模塊之間復(fù)雜的依賴關(guān)系來手動(dòng)確定模塊的加載順序了,所以利用自動(dòng)化工具來將開發(fā)階段的js腳本碎片進(jìn)行合并和優(yōu)化是非常有必要的。


          JS文件的打包:


          - 代碼編譯(TS或ES6代碼的編譯)

          - 腳本合并

          - 公共模塊識(shí)別

          - 代碼分割

          - 代碼壓縮混淆


          使用webpack處理js文件


          使用babel轉(zhuǎn)換ES6+語法

          babelES6語法的轉(zhuǎn)換工具



          腳本合并


          模塊管理文件合并這兩個(gè)功能是webpack最初設(shè)計(jì)的主要用途

          webpack默認(rèn)支持的是CommonJs規(guī)范


          公共模塊識(shí)別



          代碼分割


          為什么要進(jìn)行代碼分割?

          代碼分割最基本的任務(wù)是分離出第三方依賴庫,因?yàn)榈谌綆斓膬?nèi)容可能很久都不會(huì)變動(dòng),所以用來標(biāo)記變化的摘要哈希contentHash也很久不變,這也就意味著我們可以利用本地緩存來避免沒有必要的重復(fù)打包,并利用瀏覽器緩存避免冗余的客戶端加載。另外當(dāng)項(xiàng)目發(fā)布新版本時(shí),如果第三方依賴的contentHash沒有變化,就可以使用客戶端原來的緩存文件(通用的做法一般是給靜態(tài)資源請求設(shè)置一個(gè)很大的max-age),提升訪問速度。另外一些場景中,代碼分割也可以提供對腳本在整個(gè)加載周期內(nèi)的加載時(shí)機(jī)的控制能力。

          代碼分割的使用場景

          舉個(gè)很常見的例子,比如你在做一個(gè)數(shù)據(jù)可視化類型的網(wǎng)站,引用到了百度的Echarts作為第三方庫來渲染圖表,如果你將自己的代碼和Echarts打包在一起生成一個(gè)main.bundle.js文件,這樣的結(jié)果就是在一個(gè)網(wǎng)速欠佳的環(huán)境下打開你的網(wǎng)站時(shí),用戶可能需要面對很長時(shí)間的白屏,你很快就會(huì)想到將Echarts從主文件中剝離出來,讓體積較小的主文件先在界面上渲染出一些動(dòng)畫或是提示信息,然后再去加載Echarts,而分離出的Echarts也可以從速度更快的CDN節(jié)點(diǎn)獲取,如果加載某個(gè)體積龐大的庫,你也可以選擇使用懶加載的方案,將腳本的下載時(shí)機(jī)延遲到用戶真正使用對應(yīng)的功能之前。這就是一種人工的代碼分割。

          從上面的例子整個(gè)的生命周期來看,我們將原本一次就可以加載完的腳本拆分為了兩次,這無疑會(huì)加重服務(wù)端的性能開銷,畢竟建立TCP連接是一種開銷很大的操作,但這樣做卻可以換來對渲染節(jié)奏的控制和用戶體驗(yàn)的提升,異步模塊懶加載模塊從宏觀上來講實(shí)際上都屬于代碼分割的范疇。code splitting最極端的狀況其實(shí)就是拆分成打包前的原貌,也就是源碼直接上線。

          代碼分割的本質(zhì)


          源代碼直接上線


          代碼分割:優(yōu)點(diǎn)是過程可控,可減少首屏空白時(shí)長;缺點(diǎn)是http請求多,性能開銷大。


          Code Splitting與平衡(請求可合并的腳本;某較大的第三方庫;工具型第三方庫;某個(gè)按鈕點(diǎn)擊后加載。


          客戶端-》緩存命中率高-》性能開銷和用戶體驗(yàn)的平衡


          打包為一個(gè)腳本上線(main.bundle.js)


          優(yōu)點(diǎn):一把搞完,省事,服務(wù)器壓力??;缺點(diǎn):時(shí)間長,頁面空白期長


          代碼混淆壓縮


          webpack4中已經(jīng)內(nèi)置了UglifyJs插件,當(dāng)打包模式參數(shù)mode設(shè)置為production時(shí)就會(huì)自動(dòng)開啟


          babel的插件中也能提供代碼壓縮的處理



          splitChunks技術(shù)


          參數(shù)配置


          代碼分割實(shí)例

          單頁面應(yīng)用

          單頁面應(yīng)用只有一個(gè)入口文件,splitChunks的主要作用是將引用的第三方庫拆分出來。從下面的分包結(jié)果就可以看出,node_modules中的第三方引用被分離了出來,放在了vendors-main.[hash].js中。


          webpack --config webpack.spa.config.js


          多頁面應(yīng)用

          源碼的依賴關(guān)系為:

          entryA.js: vue vuex component10k
          entryB.js: vue axios component10k
          entryC.js: vue vuex axios component10k


          splitChunks提供了更精確的分割策略,但是似乎無法直接通過html-webpack-plugin配置參數(shù)來動(dòng)態(tài)解決分割后代碼的注入問題,因?yàn)榉职Q是不確定的。這個(gè)場景在使用chunks:'async'默認(rèn)配置時(shí)是不存在的,因?yàn)楫惒侥K的引用代碼是不需要以<script>標(biāo)簽的形式注入html文件的。

          當(dāng)chunks配置項(xiàng)設(shè)置為allinitial時(shí),就會(huì)有問題,例如上面示例中,通過在html-webpack-plugin中配置excludeChunks可以去除page和about這兩個(gè)chunk,但是卻無法提前排除vendors-about-page這個(gè)chunk,因?yàn)榇虬盁o法知道是否會(huì)生成這樣一個(gè)chunk。


          webpack中的關(guān)于Module


          大前端模塊化

          CMD規(guī)范:引用Sea.js;瀏覽器


          Webpack可識(shí)別:

          UMD規(guī)范:AMD規(guī)范(引用Require.js);瀏覽器

          CommonJs規(guī)范:原生支持,node

          ESHarmony規(guī)范:支持度暫不完善,統(tǒng)一JS全環(huán)境


          腳本合并是基于模塊化規(guī)范的


          webpack與模塊化


          webpack默認(rèn)支持的是CommonJs規(guī)范,畢竟它是nodejs支持的模塊管理方式,而沒有node哪來的webpack。但同時(shí)為了擴(kuò)展其使用場景,webpack在版本迭代中也加入了對ES harmony規(guī)范和AMD規(guī)范的兼容。


          webpack如何識(shí)別CommonJs模塊


          webpack如何識(shí)別ES Harmony模塊




          webpack是一個(gè)JS代碼模塊化的打包工具。


          資料官網(wǎng):www.webpackjs.com

          瀏覽 69
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  最新无码视频在线观看 | 青青大香蕉| 东京热不卡无码视频 | 在线无码天堂 | 亚洲骚货|