什麼是 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 的寫法。