什麼是 url-loader
會將過小的圖片轉換成 base64 格式來使用來減少載入負擔,每次都會向伺服器要圖片,就會送出多個請求。
 透過 url-loader 的 webpack 工具,可將過小圖片轉換成 base64 格式降低載入的負擔,主要是將過小圖片轉成資料格式不會產生實體的檔案。
url-loader 在 webpack.config.js 中的設定與使用
安裝 url-loader
安裝指令如下
1  | npm install url-loader --save-dev  | 
加入 uel-loader 設定,直接在 webpack.config.js 裡的 loader 中加入下面內容。
1 2 3 4 5 6 7 8 9 10 11 12  | {   test: /\.(jpe?g|png|gif)$/,   use: [     {       loader: 'url-loader',       options: {         limit: 8192,         name: '[path][name].[ext]?[hash:8]',       },     },   ], },  | 
設定說明如下
- 主要判斷檔名格式,有 jpeg 或是 png 與 gif 檔格式。
 -  options: 裡的設定
- limit:只要圖片大小低於所設定的數值,都會轉成 base64 的圖片,但超過所設定大小尺寸 8192 時,就會直接將原圖片搬移一份到 dist 資料夾中。
 -  name: '[path][name].[ext]?[hash:8]':
- [path] 路徑
 - [name] 檔名
 - .[ext] 副檔名
 - ?[hash:8] 圖片快取的更新,透過 ? 後接亂數都免圖片產生快取重覆取同張的問題
 
 
 
調整 Scss 取用圖片設定
透過 sass-loader 可配合 sytle-loader 將圖檔轉成 base64 格式後,這樣的方式比較合使不使用 extractCSS.extract([]) 的方式產出 .css 檔,這樣的方式路徑會產生問題,所以以 sytle-loader 透過 JS 直接將 CSS 傳入瀏覽器中,直接渲染畫面。
原本先前 Scss 的設定如下。
1 2 3 4  | {   test: /\.(sass|scss)$/,   use: extractCSS.extract(['css-loader', 'postcss-loader', 'sass-loader']), },  | 
修改後如下,將原本的 extractCSS.extract() 改成 style-loader,將 CSS 帶入 JS 中並透過 loader 的方式轉成 base64 格式後,在置入於 CSS 中。
1 2 3 4  | {   test: /\.(sass|scss)$/,   use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'], },  | 
加入圖檔到 src/images 資料夾中
來源檔 src 新增 images 資料夾,並將相關的圖片檔加入資料夾中
將來源檔中的圖片,在 src/ 資料夾中加入 images 資料夾,把相關的圖片加入於新增的資料夾中。
 
設定 path.resolve('src/images'), 於 resolve: [ modules: [] ]
並於 resolve: [ modules: [] ] 的陣列中加入 path.resolve('src/images'), 設定。
設定 HTML 與 Scss 檔
Scss 背景圖片 url() 路徑 resolve 省略方式使用字符 ~
在 src/index.html 檔中加入 <div id="box"></div>,用來等一下撰寫 Scss 對應樣式。
 接著到 src/index.scss 檔中加入下面內容後,透過指令 npm run dev 查看編譯結果。
1 2 3 4 5  | #box {   width: 300px;   height: 300px;   background-image: url("cat2.jpg"); }  | 
編譯結果會出現錯誤提示 Can't resolve './cat2.jpg',,在 webpack.config.js 檔使用 resolve: { modules: [] },只合適在 JS 中使用,沒辨法在 Scss 與 CSS 中使用,所以需要將透過 ~ 的字符當成前綴詞,用來與 resolve: { modules: [] } 裡設定的 path.resolve() 對應做替換路徑,調整後所編譯出來的部份才會都正常。
 
url-loader 處理 Scss 背景圖片設定 base64 方式與注意事項
正常後開啟瀏覽器查看圖片路徑,在 url() 中除了帶上 images/cat2.jpg 外,後方還加上 ?xxxxxxxx 的亂數,這部份是由 ?[hash:8] 所產生,用來使瀏覽器的快取產生動新讀取圖片的動作,每當重新執行 webpack-dev-server 之後,就會產生出新的 ?xxxxxxxx,此時的圖片會在重新載入。
 
原先的設定 limit: 8192, 修改較大一點,改成 limit: 50000,,修改如下。
1 2 3 4 5 6 7 8 9  | use: [   {     loader: 'url-loader',     options: {       limit: 55000,       name: '[path][name].[ext]?[hash:8]',     },   }, ]  | 
修改後動新執行 webpck-dev-server,讓 CSS 的圖片路徑再重新產生,此時的圖片路徑就會是以 base64 的方式產生,這樣的路徑是以 data 的方式直接存於 CSS 中,不會有實體圖片檔產生。
 
執行指令 dev run deploy 透過 webpack 執行打包,在執行完成後的 dist 資料夾裡面,是沒有 images 資料夾與圖檔產生。
 
將 base64 的設定在調回 8192 大小,重新執行 dev run deploy 後,開啟 dist 資料夾中就會產生資料夾與圖檔。
 
是否所有的圖片都要以 url-loader 將轉成 base64
如果在大的圖片都使用 url-loader 將轉成 base64 戴入網頁,這樣的方式會使得 .js 檔檔案大小過大,頁面在載入 JS 時會變的很慢。
 通常使用 url-loader 都以預設大小 8192 來設定,針對小圖示 icon 的部份處理就行。
其他參考資料
使用 webpack-dev-server 開啟專案後,使用 Scss 裡引入到背景圖片的話,會使得一定要透過 style-loader 才可以將圖片透過 JS 傳入到頁面的畫面上,這樣的方式無法在使用 VSCode 時透過插件取得 .scss 或是 .css 檔中的內容,如果要以 CSS 和圖片透過自動畫處理,會變成在開發模式下無法有圖片實體產生在輸出資料夾 dist 裡,把了一些文章另外規畫 webpack 的寫法。
