url-loader处理css中的图片资源遇到的问题

处理css中的图片资源时,我们常用的两种loader是file-loader或者url-loader,两者的主要差异在于。url-loader可以设置图片大小限制,当图片超过限制时,其表现行为等同于file-loader,而当图片不超过限制时,则会将图片以base64的形式打包进css文件,以减少请求次数。
本文的主要想说的是我们在使用file-loader或url-loader时经常出现的图片地址错误导致图片引用不到的情况,及相应解决办法。

场景复现

工程目录如下


工程目录

index页面目录

webpack配置文件中,关于图片的处理:

            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'img/[name].[hash:7].[ext]'
                }
            },

index.js文件

import './index.scss'

index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="pic"></div>
</body>
</html>

index.scss文件:

.pic{
  width:100px;
  height:100px;
  background: url('./1.jpg');
  background-size: 100px 100px;
}

当我们执行 npm run build后 查看dist中的情况如下:

image.png

我们通过服务 打开index.html会发现页面中并没有 图片,并且报错:
image.png

这是我们当然是要去看看 打包后的 css文件中的 图片路径了:

.pic{width:100px;height:100px;background:url(img/1.d1efbb3.jpg);background-size:100px 100px}
/*# sourceMappingURL=index.min.css.map?v=7b7c89f8*/

background:url(img/1.d1efbb3.jpg);,index.min.css文件竟然去自己的同级目录找img文件夹,当然找不到了
还记得我们的 dist目录情况么?

image.png

很显然img文件夹位于index.min.css上层,如果 是background:url(../img/1.d1efbb3.jpg);就对了。

然后我们尝试去修改webpack的配置文件,以达到我们的预期:

            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: '../img/[name].[hash:7].[ext]'
                }
            },

然后再npm run build
index.min.css 内的 background的图片地址的确变成了 我们想要的

.pic{width:100px;height:100px;background:url(../img/1.d1efbb3.jpg);background-size:100px 100px}
/*# sourceMappingURL=index.min.css.map?v=eef74865*/

但是悲剧的是!!!!! img 竟然被打包到了 dist文件夹的外面,不在位于dist内了,所以

现在的dist
之前的dist

是不是很抓狂……看来我们修改配置文件的方法是不对的。仔细想想,能明白其中的原因么?

打包的时候webpack会把 scss文件中的 background url 替换成我们webpack配置文件中的 options的name属性中设置的内容,同时把 scss文件中的 background url 中的图片文件 给复制到 webpack配置文件中的 options的name属性所指向路径下,关键就在这里了。

webpack配置文件中的 options的name属性所指向路径 是相对路径,那么这个路径到底是相对于谁呢?你仔细观察 会发现 它是相对于 dist 文件夹的,也就是webpack的出口路径。举个例子:

            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'img/[name].[hash:7].[ext]'
                }
            },

上面的配置,就会把图片 给复制到 dist/img/1.jpg,然后 将index.min.css 你的 background属性 改为background:url('img/1.png'),该路径也是相对路径,但是它不相对于 dist,而是相对于dist/css,因为我的css文件 并没有被输出到 dist的直接路径下,而是输出到了dist/css下,所以css 文件就会去dist/css/img/1.png去拿图片,但是图片却位于dist/img/1.png,这就最终导致了 css文件找不到图片。

配置文件复制图片是相对于 webpack 出口路径的 , css文件引用图片是相对于css文件所在路径的,如果这两个路径相同 也就是 webpack出口路径 = css文件所在路径 那么 很幸运 ,你的图片是可以找到的。但是一般情况下是不同的,我们习惯于 将出口路径 定为dist/ 然后将css文件输出到 'dist/css/' ,最终导致了引用不到图片的结果。

至此原因分析完毕。

解决方法:

在配置项内加入 publicPath 属性,设置为部署时的绝对路径

比如所 以后你的页面 会通过如下url方式让用户访问,所有前端文件都放置于

http://localhost:63342/url-loader-test/dist/

那么pubilcPath的 值就应该是 '/url-loader-test/dist/',也就是你的部署接口地址。

            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'img/[name].[hash:7].[ext]',
                    publicPath:"/url-loader-test/dist/"      //该地址不是唯一的,根据你的代码实际路由地址进行修改
                }
            },

这样做的原因是,webpack打包时,还会将图片复制到 dist/img/1.png,但是他会把css文件中的background url 改写为 publicPath + name ,本例中最后生成的index.min.css 如下:

.pic{width:100px;height:100px;background:url(/url-loader-test/dist/img/1.d1efbb3.jpg);background-size:100px 100px}
/*# sourceMappingURL=index.min.css.map?v=eef74865*/

这时css文件中的url 地址就变成了一个绝对 路由。

至此,问题解决。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 webpack介绍和使用 一、webpack介绍 1、由来 ...
    it筱竹阅读 10,933评论 0 21
  • 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过...
    阳阳阳一堆阳阅读 3,190评论 0 5
  • 目录第1章 webpack简介 11.1 webpack是什么? 11.2 官网地址 21.3 为什么使用 web...
    lemonzoey阅读 1,704评论 0 1
  • 今天,林晓月一个人在家,她很爱劳动,决定帮助爸爸妈妈干一些力所能及的家务活。 她先拿起扫帚,把家里都扫...
    智智123阅读 362评论 1 4
  • “本文参加#萨格拉斯之墓#故事征集活动,本人承诺,文章内容为原创,且未在其他平台发表过。” “我希望有一天能周游整...
    爱阿兰到永远阅读 1,625评论 0 1