webpack
作為前端最火的構建工具,是前端自動化工具鏈最重要的部分,使用門檻較高。本系列是筆者自己的學習記錄,比較基礎,希望通過問題 + 解決方式的模式,以前端構建中遇到的具體需求為出發點,學習webpack
工具中相應的處理辦法。(本篇中的引數配置及使用方式均基於webpack4.0版本
)
一. Assets資源的基本處理需求
Assets
,指專案中被引用的資源,通常為各種格式的圖片和字型檔案,當然也可能包含各式各樣其他副檔名的檔案(.json
,.xml
等),常見的圖片和文字資源的處理包括:
- 體積壓縮
- 雪碧圖合併及引用修正
- 資源的引用路徑自動替換
二. webpack處理引用資源
2.1 資源打標
webpack
通過file-loader
處理資原始檔,它會將rules
規則命中的資原始檔按照配置的資訊(路徑,名稱等)輸出到指定目錄,並返回其資源定位地址(輸出路徑,用於生產環境的publicPath
路徑),預設的輸出名是以原檔案內容計算的MD5 Hash命名的。
在webpack.config.js
中新增對圖片檔案的處理規則:
{
test:/.(jpg|png|svg|gif)/,
use:[{
loader:`file-loader`,
options:{
outputPath:`imgs/`
}
}]
}
執行打包命令可以看到png
圖片資源的名稱被替換為hash並輸出至構建資料夾。
CSS
檔案中對圖片的引用也被替換為修改後的hash名稱:
html
檔案中靜態資源引用替換需要通過html-loader
。
2.2 引用優化
構建工具通過url-loader
來優化專案中對於資源的引用路徑,並設定大小限制,當資源的體積小於limit
時將其直接進行Base64轉換後嵌入引用檔案,體積大於limit
時可通過fallback引數指定的loader
進行處理。
在webpack.config.js
中新增url-loader
相關配置:
{
test:/.(jpg|png|svg|gif)/,
use:[{
loader:`url-loader`,
options:{
limit:8129,//小於limit限制的圖片將轉為base64嵌入引用位置
fallback:`file-loader`,//大於limit限制的將轉交給指定的loader處理
outputPath:`imgs/`//options會直接傳給fallback指定的loader
}
}]
}
原始CSS
檔案中對資源的引用:
.with-img{
background-image: url(`../imgs/pic1.png`);
}
.with-small-img{
background-image: url(`../imgs/6k.gif`);
}
打包後變為如下形式,可以看到小於8k
的資源被直接內嵌進了CSS
檔案而沒有生成獨立的資原始檔:
也可以根據實際需求選擇svg-url-loader
,image-webpack-loader
等其他外掛。
2.3 sprites雪碧圖合成
雪碧圖合成,聽起來是一個顯得略高階的知識點,但它並不是必須進行的,任何一種技術都有其使用場景。有的場景下需要將圖片資源合併為獨立的雪碧圖而減少http請求的次數,有的時候或許通過url-loader
直接將其嵌入文件就可以。向量圖在不同場景下的處理方式也不相同。
webpack
官方倉庫並沒有推薦圖片的處理工具,而是採用url-loader + file-loader
作為資源處理的一般通用方案。
1.點陣圖處理
點陣圖資源,可以使用webpack-spritesmith
外掛進行處理,在webpack.config.js
的plugins
配置項中例項化外掛並傳入配置資訊:
new SpritesmithPlugin({
//設定源icons,即icon的路徑,必選項
src: {
cwd: __dirname + `/imgs/pngs`,
glob: `*.png` //正則匹配,照著填即可
},
//設定匯出的sprite圖及對應的樣式檔案,必選項
target: {
image: __dirname + `/build/imgs/sprite.png`,
css: __dirname + `/build/imgs/sprite.css`
},
//設定sprite.png的引用格式,會自己加入sprite.css的頭部
apiOptions: {
cssImageRef: `./sprite.png` //cssImageRef為必選項
},
//配置spritesmith選項,非必選
spritesmithOptions: {
algorithm: `top-down`,//設定圖示的排列方式
padding: 4 //每張小圖的補白,避免雪碧圖中邊界部分的bug
}
})
執行webpack
後可以得到sprites.css
和合成的雪碧圖:
Sprite.png:
Sprite.css:
2. 向量圖處理
開發中常用的向量圖為svg
格式,既可以使用inline-svg-loader
進行資源嵌入,也可以使用svg-sprite-loader
將向量圖資源合併為雪碧圖,具體採用哪種方案,需要由專案的實際情況來判斷。向量圖的合併原理與點陣圖稍有不同,感興趣的讀者可以自行搜尋。
原始碼中的引用:
.class1{
background-image: url(`../imgs/svgs/001-home.svg`) no-repeat 0 0;
}
使用inline-svg-loader
載入器打包後的引用:
.class1{
background-image: url("<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><path fill="#000000" d="M16 9.226l-8-6.21-8 6.21v-2.532l8-6.21 8 6.21zM14 9v6h-4v-4h-4v4h-4v-6l6-4.5z"></path></svg>") no-repeat 0 0;
}
2.4 圖片壓縮及其他
圖片資源是可以以清晰度為量化參考進行體積壓縮的,webpack
的開發社群也有現成的外掛,但不建議通過webpack
在每次打包時進行鍼對影像本身的處理,而是由UI人員處理好以後提供給開發人員。
筆者認為
webpack
對於靜態資源所需要解決的首要問題是資源定位,除此之外其他的工作應該從其中剝離,以縮短打包時間。