本文详解Webpack中如何使用file-loader解决CSS和HTML中图片引入的路径问题。通过配置file-loader,实现图片资源的正确打包与引用。文章还探讨了动态引入图片时的路径错误原因,并提供了使用require和require.context的解决方案,帮助开发者避免常见陷阱。
Webpack图片引入概述
引言部分
本文旨在展示
- Webpack在CSS文件中引用图片的方法;
- Webpack在HTML文件中引用图片的方法;
所需安装的loader:file-loader;
使用file-loader的原因:
若在页面中引入图片(涵盖img标签的src属性及background的url属性),基于Webpack开发时会遇到特定问题。
首要问题是引用路径。以background样式通过url引入背景图为例,Webpack最终将各模块打包为单一文件,导致样式中的url路径相对于入口html页面而非原始css文件所在路径,进而引发图片引入失败。该问题由file-loader解决,它能解析项目中的url引入(不限于css),按配置将图片拷贝至指定路径,并修改打包后文件的引用路径以指向正确文件。
file-loader配置与使用
安装file-loader
$ npm i -D file-loader
当前package.json配置如下:

配置webpack.config.js

在common目录下新建img文件夹,并添加图片dog.jpeg。
当前项目目录结构如下:

CSS与HTML中图片引入示例
示例一:在CSS中引入图片
编写main.css文件

在app.js中引入main.css

执行npm run build命令构建项目。
示例二:在HTML中引入图片:重新编辑app.js

执行npm run build命令构建项目。
动态引入图片的路径问题
PS:Webpack与图片引入相关问题
问题描述
- 需使用<img>标签引入多张图片
- 理想方案是将图片相关信息(文字说明、相对路径)整合至数组imageList
- 随后对imageList执行map操作以渲染图片列表
const imageList = [
{id:1,info:'中国银行',uri:'./assets/1.jpg'},
{id:2,info:'中国农业银行',uri:'./assets/2.jpg'},
{id:3,info:'中国建设银行',uri:'./assets/3.jpg'}
]
imageList.map((img)=>{
return (
<div>
{img.info}
<img src={img.uri} />
</div>
)
})
但此做法导致图片无法找到
发现图片请求路径出现异常:所有图片请求路径变为当前url拼接uri
改用import image from './assets/1.jpg'并将image赋值给src即可获取图片
此现象揭示了Webpack引入图片的机制
图片引入机制与打包原理
问题原因分析
Q1:这两种方式的区别何在?
A2:主要差异在于资源路径
- 赋给src相对路径:导致资源请求路径变为当前url加上src的值
- 赋给src import的文件:首先import返回一个字符串,该字符串为文件打包后(在静态目录下)的绝对路径。因此当前请求图片路径变为端口号加上import的值
最后请求图片路径的解释如下:
- 若src的值以slash开头,则被视为以静态文件为根目录的绝对路径
- 若src的值不以slash开头,则被视为当前路径的相对路径
总结而言:静态服务器可被视为文件系统,这些uri即为文件路径
Q2:图片是如何被Webpack打包的?
A2:仅针对图片的import操作:
打包时机:项目中的图片并非全部会被打包,经尝试发现通过import或background:url(image path)引入的图片才会被打包
打包位置:通过配置file-loader设定
{
test: /\.(jpg|png|svg|pdf)$/,
exclude: /font.*\.svg$/,
loader: 'file-loader?name=[path][name].[hash].[ext]'
}
//根据这样的设置,webpack会将所有**使用到的图片全部加载到当前path并且名字不变但是加上.hash.后缀**
Q3:img src的值可以是什么?background:url的值又可以是什么?
A3:
img src:
- 路径(url)
- require(或import的值)
- data url(base64)
background:url:
- 路径(相对)
- data url(base64)
Q4:为何在CSS中使用background-url()可使用图片的相对路径,而在JS文件中不能使用相对路径赋值给src?
A4:首先说明我观察到的区别
- src:会发起请求,请求静态的外部文件资源(无论src的值是什么(除base64外)都会发送请求)
- CSS background:不会发送请求
Webpack对它们的处理方式截然不同:
- - src:url :不会被Webpack处理
- - src:require():会被Webpack处理
- - background:url:会被Webpack处理
总结:使用import或require或background都会被Webpack的file-loader视为依赖模块处理:
- - 打包时执行到引入部分(import。。。)
- - 将对应的静态文件打包至配置好的位置
- - 生成打包后的绝对路径并赋值给引入部分
Q5:客户端图片引入的方式有几种?它们分别基于什么原理?
A5:所谓客户端图片:即不通过http请求方式获取的图片
- 通过background:url('./****')
- 通过background:url(图片base64)
- 通过src=图片base64
- 通过src=require('./******')
file-loader作用与高级解决方案
其他知识补充
K1:至此终于明白file-loader的作用
当其他模块需要引用文件时,file-loader会将对应文件依照name属性要求的文件路径和文件名进行打包。通过计算文件大小,若小于limit的值,则将文件转为base64赋给需要这些文件的位置;若大于limit的值,则将文件打包后的路径赋给需要这些文件的位置
我的疑问:
网上有观点称~作为src值的开头可将这部分的请求作为依赖模块处理,但我未尝试成功
我的解决方案
- 由于尚不清楚如何给background-url编程以循环引入图片,我决定采用:
- 因此我采用编写一个对象数组,对对象数组进行map,return<img src={require(bank.img+'')}>
const BANK_LIST = [
{name: '中国银行', img: './assets/bank-logo-6.png', id: 1},
{name: '中国建设银行', img: './assets/bank-logo-7.png', id: 2},
{name: '兴业银行', img: './assets/bank-logo-8.png', id: 3}
]
BANK_LIST.map((bank)=>{
return (
<img src={require(bank.img+'')} />
)
})
我的另一种解决方案(因项目中eslint要求不支持动态引入文件)
使用Webpack自带的require.context('pathToDirectory'),它可以循环地将一个目录下的所有文件引入
const BANK_LIST = {
'./bank-logo-6.png': {name: '中国银行', id: 1},
'./bank-logo-7.png': {name: '中国建设银行', id: 2},
'./bank-logo-8.png': {name: '兴业银行', id: 3}
}
const pathToImages = require.context('./assets');
const originalBankList = pathToImages.keys().map((key) => {
return Object.assign({}, BANK_LIST[key], {url: pathToImages(key)})
});
//这时候originalBankList的每一项会变成
{name: '中国银行', id: 1,url: "/app/src/containers/WisePort/CheckoutCounterContai…/bank-logo-1.9f949c516315756e18c0cb7d572f4d2c.png"'}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。