【webpack核心】- 12、loader-3 圖片處理

上節loader加載器 把css代碼轉成js代碼,以變進行語法樹分析
loader也可以把圖片進行打包
靜態圖片:

  1. 頁面直接使用<img src='' alt=''> 來使用,在頁面中寫死的
  2. 用js來生成的

動態圖片:通過ajax請求服務器,從服務器得到的圖片路徑,這些是不需要前端進行處理的

1、打包圖片爲 base64格式 / 文件路徑格式

//main.js裏引入圖片模塊
var src = require('./assets/logo.png')   //commonjs裏面沒有導出,得到的是一個空對象{}
var img = document.createElement('img');
img.src = src;
document.body.appendChild(img);

在這裏插入圖片描述
如上寫法,npx webpack打包會報錯:因爲webpack 用utf-8格式將圖片當成js讀出來讀的是二進制格式的代碼沒辦法進行語法樹分析,所以要用loader加載器,把二進制數據給loader,loader將器處理成js代碼

// ./loaders/img-loader.js   --loader 導出一個函數
function loader(sourceCode){
	//console.log(sourceCode);  //亂碼,下面加loader.raw = true;纔會用二進制格式去讀
	console.log('文件數據大小(字節):',buffer.byteLength);
	//這裏sourceCode 傳進來的是個二進制buffer,但webpack確默認把傳進來但內容都當字符串來讀,所以在這裏打印sourceCode會亂碼
	var content = getBase64(sourceCode);
	console.log(content);  //這是buffer格式的sourceCode 轉爲base64格式的內容
	return `module.exports = \`${content}\``;
}
loader.raw = true;   //raw是函數loader上的靜態屬性,true時表示原始格式的數據
//這樣webpack處理的時候,看到來loader函數上有個靜態屬性raw爲true,那處理的時候就不會用字符串來讀sourceCode,而是用原格式buffer讀,比如:如果傳的sourceCode是buffer  那上面打印的還是buffer
module.exports = loader;

function getBase64(buffer){
	return 'data:image/png;base64,'+ buffer.toString('base64');  //buffer轉base64
}

在這裏插入圖片描述導出的圖片可以是base64格式
二進制的數據用buffer來表示

// webpack.config.js
module.exports = {
	mode:'development',
	module:{
		rules:[
			{
				test:/\.(png)|(jpg)|(gif)$/,
				use:['./loaders/img-loader']
			}
		]
	}
}

打包後dist裏的代碼:
在這裏插入圖片描述
在這裏插入圖片描述


也可以打包圖片爲 文件路徑格式

var loaderUtil = require("loader-utils")  //npm 安裝的模塊

function loader(buffer) { //給的是buffer
    console.log("文件數據大小:(字節)", buffer.byteLength);
    var { limit = 1000, filename = "[contenthash].[ext]" } = loaderUtil.getOptions(this);
    if (buffer.byteLength >= limit) {  //超過限制用文件
        var content = getFilePath.call(this, buffer, filename);
    }
    else{  //否則用base64
        var content = getBase64(buffer)
    }
    return `module.exports = \`${content}\``;
}

loader.raw = true; //該loader要處理的是原始數據

module.exports = loader;

function getBase64(buffer) {
    return "data:image/png;base64," + buffer.toString("base64");
}

function getFilePath(buffer, name) {
    var filename = loaderUtil.interpolateName(this, name, {
        content: buffer
    });
    this.emitFile(filename, buffer);
    return filename;
}

問題:hash、chunkhash、contenthash的區別
contenthash – 根據具體某個文件生成的hash
hash – 總資源列表生成的hash
chunkhash – 根據chunk 資源生成的hash

2、webpack.config.js中自行配置

module.exports = {
	module:{
		rules:[
			{
				test:/\.(png)|(jpg)|(gif)$/,
				use:['./loaders/img-loader.js','./loaders/css-loaders.js']
			}
		]
	}
}

優化配置:在webpack 配置加載器的時候進行配置–options裏自行規定

module.exports = {
	module:{
		rules:[
			{
				test:/\.(png)|(jpg)|(gif)$/,
				use:[
					{
					loader:'./loaders/img-loader.js',
					options:{
						limit:3000,  //資源限定爲多大字節,3000字節以內使用base64, 超過3000使用圖片
						filename:"img-[contenthash:5].[ext]",  //也可以用總hash, chunkhash,這裏contenthash 根據資源內容而定,最合適}
					}
				]
			}
		]
	}
}

總結:

  1. webpack會把require(’./assets/index.css’) require()後面的路徑當作依賴
  2. 在編譯 – 模塊解析時, 需要讀取require()的依賴, webpack 會把圖片當成js來讀取,讀到的是二進制的buffer,需要用加載器loader 把二進制數據 轉換成js代碼,以便webpack 進行抽象語法樹分析
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章