当我们在index.js引入一个图片文件,如:
var Pic = require('./asset/demo-pic.jpg')
or
import Pic from './asset/demo-pic.jpg'
然后不是说webpack也可以打包图片吗,所以直接进行打包命令,最好报错:
$ npm run bundle
> webpack-demo@1.0.0 bundle C:\Users\Administrator\Desktop\webpack-demo
> webpack
Hash: 9e16560f2dc251f1a1da
Version: webpack 4.39.2
Time: 220ms
Built at: 2019-08-26 13:31:16
1 asset
Entrypoint main = bundle.js
[0] ./src/asset/demo-pic.jpg 281 bytes {0} [built] [failed] [1 error]
[1] ./src/index.js + 3 modules 947 bytes {0} [built]
| ./src/index.js 192 bytes [built]
| ./src/common/header.js 256 bytes [built]
| ./src/common/nav.js 238 bytes [built]
| ./src/common/footer.js 256 bytes [built]
ERROR in ./src/asset/demo-pic.jpg 1:0
Module parse failed: Unexpected character '?' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
@ ./src/index.js 4:0-38
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! webpack-demo@1.0.0 bundle: `webpack`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the webpack-demo@1.0.0 bundle script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Program Files\nodejs\node_cache\_logs\2019-08-26T05_31_16_980Z-debug.log
从上面报错信息,可以知道jpg图片文件出现打包错误,为什么呢?
↓ 因为默认配置里并没有对图片文件的打包说明配置,所以webpack并不知道你要干什么,那怎么解决呢?
↓ 在webpack.config.js
中配置一个模块规则,如下:
module.exports = {
mode: 'production',
// mode: 'development',
entry:{
"main": './src/index.js'
},
module:{
rules:[{
test: /\.jpg$/,
use:{
loader: 'file-loader'
}
}]
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'bundle')
}
}
↓ 参数解释:
module:
即为定义模块规则的地方,比如对于那些TS,css预编译器,图片格式文件的都是这里定义规则;
rules:
这里定义的就是规则集合,是一个数组;
test:
这里可以写一些正则校验,主要用来匹配相应的文件;
use:
这里呢,他是跟匹配test规则的文件进行使用相应的loader模块,当然这里的模块可以看文档,都有一一对应,如果没有安装就会报错;
↓ 配置完成后,我们下载相应的loader翻译器,在进行打包命令:
$ npm run bundle
> webpack-demo@1.0.0 bundle C:\Users\Administrator\Desktop\webpack-demo
> webpack
Hash: 5b8e1a23f19135a790aa
Version: webpack 4.39.2
Time: 329ms
Built at: 2019-08-26 14:16:53
Asset Size Chunks Chunk Names
bundle.js 1.51 KiB 0 [emitted] main
c4ca5ccbf8b396d4a377730f93f18814.jpg 77 KiB [emitted]
Entrypoint main = bundle.js
[0] ./src/asset/demo-pic.jpg 82 bytes {0} [built]
[1] ./src/index.js + 3 modules 972 bytes {0} [built]
| ./src/index.js 217 bytes [built]
| ./src/common/header.js 256 bytes [built]
| ./src/common/nav.js 238 bytes [built]
| ./src/common/footer.js 256 bytes [built]
完成,此时在bunder输出文件夹中,可以看到多出了一个打好包的图片,这个图片名是文件内容的 MD5 哈希值;
file-loader还有很多可以进行配置的属性,具体可以看官网:
https://webpack.docschina.org/loaders/file-loader/
来展示file-loader
的一个代码片段:
module: {
rules: [{
test: /\.(jpg|png|gif)$/,
use: [{
loader: 'file-loader',
options: {
name(file) {
if (process.env.NODE_ENV === 'development') {
return '[path][name].[ext]';
}
return '[hash].[ext]';
}
}
}]
}]
},
浅释一下:
这里校验的文件结尾为jpg/png/gif的文件都会匹配,然后这些文件都可以使用file-loader进行翻译处理,option是它的可选属性,是判断当前打包环境是开发还是生产,来进行输出的不同,其中[path].[name].[ext]
打包好后就是输出该文件在开发时的文件目录及原始名称,如图:
我们在index.js中加一段代码:
import Header from './common/header'
import Nav from './common/nav'
import Footer from './common/footer'
import Pic from './asset/demo-pic.jpg'
console.log('pic',Pic); // 添加的代码
new Header();
new Nav();
new Footer();
打包原理(file-loader为例子):
我们行打包后,再打开index.html文件,发现控制台输出的是[hash].[ext],这不就是打包后生成在bundle文件夹中的jpg文件吗
loader打包原理,webpack执行打包时,会根据配置文件的属性规则,如file-loader中,把正则匹配的文件 → 扔进bundle文件夹中 → 然后根据file-loader的翻译进行打包这些文件并且生成 → 最后把变量值返回到index.js
所以我们看到的控制台输出的是打包后的文件名
那根据这个原理我们不妨可以这么测试一下:
import Pic from './asset/demo-pic.jpg'
var img = new Image();
img.src = Pic;
var dom = document.getElementById('app');
dom.append(img);
如果你读懂了上面说的,那这个运行inde.html时页面输出的就是图片啦
outputPath:
输出文件保存在哪?看代码
outputPath: 'images/asset/'
url-loader官网: https://webpack.docschina.org/loaders/url-loader/
module: {
rules: [{
test: /\.(jpg|png|gif|svg)$/,
use: [{
loader: 'url-loader',
options: {
name(file) {
if (process.env.NODE_EVN === 'development') {
return '[name]_[hashType].[ext]';
}
return '[name][hash].[ext]';
},
limit: 10240,
outputPath: 'images/asset/'
}
// options: {
// name: '[path][name].[ext]'
// }
}]
}]
},
解析:
这里使用url-loader
,给了边界值limit,当匹配的文件小于10240个字节(10kb)就安装url-loader解析翻译,他会将文件转成base64,但是大于这个Limit就会打包成一个图片格式,所以啊配合url-loader可以大大减少请求量!
关于图片的loader就到这~
#下一篇讲【处理css样式的loader~】