图片引入方式
在实际的生产过程中有以下几种引入图片的方式
直接在html写入
标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack html打包</title>
</head>
<body>
<h1 id="title">
hello Webpack 2021
</h1>
<img src="./imgs/webpack.jpg">
</body>
</html>
在css中中引入背景图片
.main{
width: 300px;
height: 300px;
background-image: url(./imgs/angular.jpg);
background-repeat: no-repeat;
background-size: 100% auto;
border: 3px solid green;
}
在js中创建图片引入
import img from './imgs/webpack.jpg';
var imgElement = document.createElement('img');
imgElement.src = img;
document.body.appendChild(imgElement);
url-loader
在 webpack 中引入图片需要依赖 url-loader 这个加载器。
安装
npm install url-loader -D
当然也可以将其写入配置中,以后与其他工具模块一起安装
"devDependencies": {
"css-loader": "^6.3.0",
"file-loader": "^6.2.0",
"html-loader": "^2.1.2",
"html-webpack-plugin": "^5.3.2",
"less": "^4.1.2",
"less-loader": "^10.0.1",
"style-loader": "^3.3.0",
"url-loader": "^4.1.1",
"webpack": "^5.58.1",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.3.1"
}
在 webpack.config.js 文件中配置如下
module: {
loaders: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 图片大小小于20kb,就会base64处理
limit: 20 * 1024,
// url-loader默认使用es6模块化解析,html-loader引入图片使用的是commonjs规范
// 关闭url-loader的es6模块化,使用commonjs解析
esModule: false,
// outputPath: 'assets'
// 图片编译之后重命名
// [hash:10]获取图片hash前10位 [ext]取文件的原扩展名
name:'[hash:10].[ext]'
}
}
],
}
]
}
test 属性代表可以匹配的图片类型,除了 png、jpg、gif 之外也可以添加 svg 等,以竖线隔开即开。
loader 后面中的options 中增加关于 url-loader 的一些配置项:
- limit 字段代表图片打包限制,这个限制并不是说超过了就不能打包,而是指当图片大小小于限制时会自动转成 base64 码引用。上例中大于 20kb 字节的图片正常打包,小于 20kb 的图片以 base64 的方式引用。默认是无limit的。
- esModule 关闭url-loader的es6模块化,使用commonjs解析。
- name 图片编译之后重命名。
- fallback 指定当前目标文件大小超出处理限制时,要使用的备用加载程序。 具体可以参考 url-loader的官方文档。
然后通过以上配置,在命令行控制台输入打包命令后,可以看到构建页面如下所示:
最终输出的打包的目录文件如下:
html-loader
打包后发现可以发现在html中的引入的图片路径写死的,并不会相对于build,导致无法找到该图片,使用html-loader来处理html中的图片。
安装
安装并配置
npm i -D html-loader
在webpack.config.js 中配置文件如下:
{
test: /\.html/,
// 处理html文件中的img图片,负责引入img,从而可以被url-loader处理
loader: 'html-loader'
}
再次打包之后可以看到html中的文件可以正常访问到。
遇到的问题
在项目实践中使用的是 webpack5 的版本打包构建的文件,
问题描述
使用webpack5进行图片资源打包时,打包后图片打不开,并且有重复的图片资源。
问题分析
1、webpack.config.js配置文件代码
/**
* webpack 的配置文件
* 指示 webpack 都做哪些工作
* loader: 1. 下载 2. 使用(配置loader)
* plugins: 1. 下载 2. 引入 3. 使用
* */
// resolve 用于拼接绝对路径的方法
const path = require('path');
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// webpack 打包的入口起点
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'main.js',
// 输出的路径
// --dirname是node.js的一个全局变量,表示当前执行脚本所在的目录
path: resolve(__dirname, 'build'),
publicPath: './'
// publicPath: '../build/'
},
// loader的配置
module: {
// 详细的loader配置
rules: [
{
// 匹配哪些文件
test: /\.css$/,
// 使用哪些loader进行处理
use: [
// use数组中loader执行顺序从下网上执行
// 创建style标签,将js中的样式资源进行插入,添加到head中生效
'style-loader',
// 将css文件变成commonjs模块加载到js中,里面的内容是字符串
'css-loader'
]
},
{
// 匹配哪些文件
test: /\.less$/,
// 使用哪些loader进行处理
use: [
// use数组中loader执行顺序从下网上执行
// 创建style标签,将js中的样式资源进行插入,添加到head中生效
'style-loader',
// 将css文件变成commonjs模块加载到js中,里面的内容是字符串
'css-loader',
// 将less文件编译成css文件
// 需要下载 less 和 less-loader
'less-loader'
]
},
{
// test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
// 图片大小小于20kb,就会base64处理
limit: 20 * 1024,
// url-loader默认使用es6模块化解析,html-loader引入图片使用的是commonjs规范
// 关闭url-loader的es6模块化,使用commonjs解析
esModule: false,
// outputPath: 'assets'
// 图片编译之后重命名,[hash:6]获取图片hash前6位 [ext]取文件的原扩展名
name:'[hash:10].[ext]'
}
}
]
},
// {
// test: /\.(html|js|css|less|jpg|png|gif)/,
// loader: 'file-loader',
// options: {
// name: '[hash:6].[ext]'
// }
// },
{
test: /\.html/,
// 处理html文件中的img图片,负责引入img,从而可以被url-loader处理
loader: 'html-loader'
}
]
},
// plugins的配置
plugins: [
// 详细的plugins的配置
// html-webpack-plugin
new HtmlWebpackPlugin({
title: 'test',
// 功能:生成一个 HTML5 文件, 在 body 中使用 script 标签引入你所有 webpack 生成的 bundle(js/css)。
template: './src/test.html'
})
],
// 模式 默认是生产环境 production
mode: 'development',
// 开发服务器 devServer,主要用于自动化(自动化编译,自动化打开浏览器,有变动自动刷新浏览器~)
// 只会在内存中进行编译打包,不会有任何输出
devServer: {
static: {
directory: resolve(__dirname, 'build'),
},
hot: true,
// 端口号
port:8080,
// 自动打开默认浏览器
open:true,
// 启用 gzip 压缩
compress:true,
proxy:{
"/api":{
// 目标地址
target:"http://localhost:8888",
// 路径重写,默认情况下,我们的/api也会被写入到URL中,如果希望删除,可以使用
pathRewrite:{
"^/api":""
},
// 默认情况下不接受转发到https的服务器,如果希望支持,设置为false
secure:false,
// 是否更新代理后请求headers中的host地址
changeOrigin:true
}
}
},
// watch: true
}
发现配置文件没有问题,打包时图片使用了url-loader和file-loader。考虑是不是这两个loader的问题。
到webpack官网查看资料以后,发现官方这样描述:
当在 webpack 5 中使用旧的 assets loader(如 file-loader/url-loader/raw-loader 等)和 asset 模块时,你可能想停止当前 asset 模块的处理,并再次启动处理,这可能会导致 asset 重复,你可以通过将 asset 模块的类型设置为 ‘javascript/auto’ 来解决。 所以我们在webpack5使用这些loader时需要添加:
type: 'javascript/auto'
这样以后再使用webpack打包,发现图片可以正常访问。