1 概述
引入图片有三种方式。
- js中创建图片引入
- css中引入图片
<img>
标签引入图片
引入图片的语法很简单,关键是图片路径问题。
如何能正确找到图片资源,这是我们关心的。
2 js中创建图片引入
示例代码:
import logo from "./logo.png"
let img = new Image();
console.log(logo)
img.src = logo;
document.body.appendChild(img)
然而,运行时报错:
ERROR in ./src/logo.png 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/bbb.js 9:0-30 11:12-16 12:10-14
@ ./src/aaa.js 7:0-18
webpack 5.21.2 compiled with 1 error in 2960 ms
报错说:需要合适的loader去加载图片。
需引入file-loader
或img-loader
,并增加webpack配置。
1. file-loader 实现图片加载
file-loader
默认会在内部生成一张图片到build目录下,返回生成的图片的路径。
安装:
npm install file-loader -D
webpack配置:
module.exports = {
module: {//模块
rules: [//规则,多个loader
{
test: /\.(png|jpg|gif)$/,
use: "file-loader"
}
]
}
}
运行查看结果。
2. url-loader 实现小图片base64化
安装:
npm install url-loader -D
webpack配置:
module.exports = {
module: {//模块
rules: [//规则,多个loader
{
test: /\.(png|jpg|gif)$/,
use: "file-loader"
},
{
test: /\.(png|jpg|gif)$/,
//可以做限制,如:图片小于200k,用base64转化,否则用url-loader产生真实图片
use: {
loader: "url-loader",
options: {
limit: 200 * 1024,
}
}
},
]
}
}
运行,可以看到小于200k的图片是base64的内容。
使用base64的用处:可以不用走网络请求加载,但是base的内容会比原图片大三分之一。
3 css中加载图片
使用CSS语法:background: url('')
示例代码:
div {
width: 400px;
height: 400px;
background: url('./logo.png');
}
然而,运行时报错:Error: Automatic publicPath is not supported in this browser
ERROR in ./src/index.styl
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
Error: Automatic publicPath is not supported in this browser
报错说:此浏览器不支持自动publicPath。
说明需要手动配置一个publicPath
publicPath就是我们网站的域名。
修改webpack配置:
module.exports = {
output: {
filename: "bundle.[hash:8].js",//打包后的文件名
path: path.resolve(__dirname, "dist"),//打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
publicPath: "http://localhost:3000/"
},
}
主要是在output
中添加publicPath
:
publicPath: "http://localhost:3000/"
本地调试就用本机域名地址。
4 <img>
标签引入图片
使用标签:<img src=""></img>
示例代码:
<img src="./logo.png"></img>
运行之后,浏览器报错:
GET http://localhost:3000/logo.png 404 (Not Found)
因为我们的图片并不在打包目录下,自然是找不到的。
此时我们需要用html-withimg-loader
来解析html中的图片路径。
安装:
npm install html-withimg-loader -D
配置webpack:
module.exports = {
module: {//模块
rules: [//规则,多个loader
{
test: /\.html$/,
use: "html-withimg-loader"
}
]
}
}
运行发现img标签下的图片加载失败,
报错内容:
GET http://localhost:3000/%7B%22default%22:%22http://localhost:3000/e702de51403af91429843c1df58d3d49.png%22%7D 404 (Not Found)
查看资源文件发现img加载的路径变得奇奇怪怪:
<img src="{"default":"http://localhost:3000/e702de51403af91429843c1df58d3d49.png"}"></img>
问题原因是:
那是和html-webpack-plugin
发生了冲突 同时也因为 file-loader
版本冲突了
首先你需要把html-webpack-plugin
中针对代码优化相关的配置注释掉:
plugins: [//存放所有插件
new HtmlWebpackPlugin({
template: "./src/index.html",//模版文件(源文件)地址
filename: "index.html",//打包后文件名
// minify:false,
// minify: {
// removeAttributeQuotes: true,//删除双引号
// collapseWhitespace: true,//折叠空行(变成一行)
// },
hash: true,//引用时文件名加上hash戳
}),
],
然后,如果你的file-loader
版本是 5.* 或以上版本,需要在webpack中修改file-loader
配置:
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'file-loader',
options: {
esModule: false
}
}]
},
{
test: /\.html$/,
use: "html-withimg-loader"
}
如果是url-loader
与html-withimg-loader
搭配使用出现这个问题,解决办法相同。
主要是在配置中新增:
options: {
esModule: false
}
默认是true 使用esModule 改为false就可以打包了
查看结果:
<img src="http://localhost:3000/e702de51403af91429843c1df58d3d49.png"></img>
图片显示正常。
5 资源分目录打包
可以给css、图片 等静态资源指定一个打包目录。
webpack配置:
module.exports = {
plugins: [//存放所有插件
new MiniCssExtractPlugin({
filename: "css/main.css"//抽离css之后输出的文件名
}),
],
module: {//模块
rules: [//规则,多个loader
{
test: /\.(png|jpg|gif)$/,
//可以做限制,如:图片小于200k,用base64转化,否则用file-loader产生真实图片
use: {
loader: "url-loader",
options: {
esModule: false,
limit: 200 * 1024,
outputPath:"img/"
}
}
},
]
}
}
主要是修改了两处:
filename: "css/main.css"//抽离css之后输出的文件名
outputPath:"img/"
css输出路径增加文件夹;
图片加载时增加导出文件夹路径;
6 指定图片域名
可以指定只有加载图片资源时添加指定的域名路径。
webpack配置:
module.exports = {
output: {
filename: "bundle.[hash:8].js",//打包后的文件名
path: path.resolve(__dirname, "dist"),//打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
},
module: {//模块
rules: [//规则,多个loader
{
test: /\.(png|jpg|gif)$/,
//可以做限制,如:图片小于200k,用base64转化,否则用file-loader产生真实图片
use: {
loader: "url-loader",
options: {
esModule: false,
limit: 200 * 1024,
outputPath:"img/",
publicPath: "http://localhost:3000/",
}
}
},
]
}
}
将output
中的publicPath: "http://localhost:3000/",
删掉;
往rules中图片loader里加入publicPath: "http://localhost:3000/",
;
这样可以实现只在加载图片时,采用域名的形式加载资源,其他css和js还是相对路径形式加载。
相当于部分添加域名。
但奇怪的是,图片loader中加了publicPath之后,outputPath属性就不生效了。谁给解释一下?但不影响图片加载。
暂无评论