webpack是用JS寫的,運行在node環境,所以默認webpack打包的時候只會處理JS之間的依賴關系!!!
如果你不相信,你可以創建如下類似的代碼嘗試在JS中導入圖片
然后運行打包命令就發生報錯現象(不要編寫webpack.config.js就可以直接打包,這是webpack4新加的功能,但是入口文件必須是src/index.js文件必須要有)
提示我們需要提供相關的loader來處理圖片類型的文件。
因為像 .png
這樣的文件不是一個 JavaScript 模塊,你需要配置 webpack 使用 file-loader 或者 url-loader 去合理地處理它們。
轉換資源 URL 的好處是:
file-loader 可以指定要復制和放置資源文件的位置,以及如何使用版本哈希命名以獲得更好的緩存。此外,這意味着 你可以就近管理圖片文件,可以使用相對路徑而不用擔心部署時 URL 的問題。使用正確的配置,webpack 將會在打包輸出中自動重寫文件路徑為正確的 URL。
url-loader 允許你有條件地將文件轉換為內聯的 base-64 URL (當文件小於給定的閾值),這會減少小文件的 HTTP 請求數。如果文件大於該閾值,會自動的交給 file-loader 處理。
我們之前require('./banner.jpg')
圖片是為了得到圖片的路徑,並且同時把圖片放到打包文件夾里面,注意並不是把圖片導入到JS里面,如果你了解 require
原理,其實就是使用 fs.readFile
同步讀取文件中的內容做相對應的解析,默認只支持 js
和 json
文件類型,導入其他的文件類型就無法識別了,所以就報錯了。
const src = require('./banner.jpg') const app = document.getElementById('app'), const img = new Image() img.src = src document.appendChild(img) console.log('添加圖片')
如果有了loader,在配置中讀取到 .jpg
結尾要用 file-loader
來處理,那么會把 require('./banner.jpg')
通過特定的語法解析成一個路徑 0a8258fdc76b3a6c543be9d75debf066.jpg
,那么此時 src
變量就是圖片路徑了。
總結:file-loader 將文件上的 import
/ require
()解析為 url,並將該文件發射到輸出目錄中。
url-loader 可以識別圖片的大小,然后把圖片轉換成base64,從而減少代碼的體積,如果圖片超過設定的現在,就還是用 file-loader來處理。如果不在乎體積,不想轉換成base64,可以不要配這個loader。這里提一句,不要把字體也用 file-loader 來處理,把字體文件轉成base64是瀏覽器無法識別的,這是錯誤的操作。
const path = require('path') module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.(jpg|png)$/, loader: 'url-loader' } ] } }
提示:給圖片配了 url-loader 在配置里面就不要再給圖片配 file-loader 了 ,因為 url-loader 默認會使用 file-loader 來處理圖片的路徑關系的,只是加了個當圖片太大把路徑轉成了base64的功能。
使用時參考如下代碼,注意esModule參數是表示是否使用es6模塊的導出,默認是啟用的,根據實際情況使用
const path = require('path') module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.(png|svg|jpe?g)$/i, loader: 'url-loader', options: { esModule: false } }, { test: /\.(woff|woff2|eot|ttf|otf)$/i, loader: 'file-loader', options: { esModule: false } } ] } }