webpack4.0各個擊破(3)—— Assets篇

webpack做爲前端最火的構建工具,是前端自動化工具鏈最重要的部分,使用門檻較高。本系列是筆者本身的學習記錄,比較基礎,但願經過問題 + 解決方式的模式,之前端構建中遇到的具體需求爲出發點,學習webpack工具中相應的處理辦法。(本篇中的參數配置及使用方式均基於webpack4.0版本html

一. Assets資源的基本處理需求

Assets,指項目中被引用的資源,一般爲各類格式的圖片和字體文件,固然也可能包含各式各樣其餘擴展名的文件(.json,.xml等),常見的圖片和文字資源的處理包括:前端

  • 體積壓縮
  • 雪碧圖合併及引用修正
  • 資源的引用路徑自動替換

二. webpack處理引用資源

2.1 資源打標

webpack經過file-loader處理資源文件,它會將rules規則命中的資源文件按照配置的信息(路徑,名稱等)輸出到指定目錄,並返回其資源定位地址(輸出路徑,用於生產環境的publicPath路徑),默認的輸出名是以原文件內容計算的MD5 Hash命名的。webpack

webpack.config.js中添加對圖片文件的處理規則:web

{
    test:/\.(jpg|png|svg|gif)/,
    use:[{
      loader:'file-loader',
      options:{
        outputPath:'imgs/'
      }
    }]
  }

執行打包命令能夠看到png圖片資源的名稱被替換爲hash並輸出至構建文件夾。json

CSS文件中對圖片的引用也被替換爲修改後的hash名稱:
api

html文件中靜態資源引用替換須要經過html-loader前端構建

2.2 引用優化

構建工具經過url-loader來優化項目中對於資源的引用路徑,並設定大小限制,當資源的體積小於limit時將其直接進行Base64轉換後嵌入引用文件,體積大於limit時可經過fallback參數指定的loader進行處理。svg

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.jsplugins配置項中實例化插件並傳入配置信息:

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對於靜態資源所須要解決的首要問題是資源定位,除此以外其餘的工做應該從其中剝離,以縮短打包時間。

相關文章
相關標籤/搜索