處理css中的圖片資源時(shí)吊骤,我們常用的兩種loader是file-loader或者url-loader翩肌,兩者的主要差異在于箱蟆。url-loader可以設(shè)置圖片大小限制帮非,當(dāng)圖片超過(guò)限制時(shí),其表現(xiàn)行為等同于file-loader博个,而當(dāng)圖片不超過(guò)限制時(shí)怀樟,則會(huì)將圖片以base64的形式打包進(jìn)css文件,以減少請(qǐng)求次數(shù)盆佣。
本文的主要想說(shuō)的是我們?cè)谑褂胒ile-loader或url-loader時(shí)經(jīng)常出現(xiàn)的圖片地址錯(cuò)誤導(dǎo)致圖片引用不到的情況往堡,及相應(yīng)解決辦法。
場(chǎng)景復(fù)現(xiàn)
工程目錄如下
webpack配置文件中共耍,關(guān)于圖片的處理:
{
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;
}
當(dāng)我們執(zhí)行 npm run build
后 查看dist中的情況如下:
我們通過(guò)服務(wù) 打開(kāi)index.html會(huì)發(fā)現(xiàn)頁(yè)面中并沒(méi)有 圖片虑灰,并且報(bào)錯(cuò):
這是我們當(dāng)然是要去看看 打包后的 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文件竟然去自己的同級(jí)目錄找img文件夾痹兜,當(dāng)然找不到了
還記得我們的 dist目錄情況么穆咐?
很顯然
img
文件夾位于index.min.css
上層,如果 是background:url(../img/1.d1efbb3.jpg);
就對(duì)了。
然后我們嘗試去修改webpack的配置文件对湃,以達(dá)到我們的預(yù)期:
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
},
然后再npm run build
index.min.css 內(nèi)的 background的圖片地址的確變成了 我們想要的
.pic{width:100px;height:100px;background:url(../img/1.d1efbb3.jpg);background-size:100px 100px}
/*# sourceMappingURL=index.min.css.map?v=eef74865*/
但是悲劇的是Q陆小!J煳尽9槁丁! img 竟然被打包到了 dist文件夾的外面斤儿,不在位于dist內(nèi)了,所以
是不是很抓狂……看來(lái)我們修改配置文件的方法是不對(duì)的恐锦。仔細(xì)想想往果,能明白其中的原因么?
打包的時(shí)候webpack會(huì)把 scss文件中的 background url 替換成我們webpack配置文件中的 options的name屬性中設(shè)置的內(nèi)容一铅,同時(shí)把 scss文件中的 background url 中的圖片文件 給復(fù)制到 webpack配置文件中的 options的name屬性所指向路徑下陕贮,關(guān)鍵就在這里了。
webpack配置文件中的 options的name屬性所指向路徑 是相對(duì)路徑潘飘,那么這個(gè)路徑到底是相對(duì)于誰(shuí)呢肮之?你仔細(xì)觀察 會(huì)發(fā)現(xiàn) 它是相對(duì)于 dist
文件夾的,也就是webpack的出口路徑卜录。舉個(gè)例子:
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'img/[name].[hash:7].[ext]'
}
},
上面的配置戈擒,就會(huì)把圖片 給復(fù)制到 dist/img/1.jpg
,然后 將index.min.css 你的 background屬性 改為background:url('img/1.png')
艰毒,該路徑也是相對(duì)路徑筐高,但是它不相對(duì)于 dist
,而是相對(duì)于dist/css
丑瞧,因?yàn)槲业腸ss文件 并沒(méi)有被輸出到 dist
的直接路徑下柑土,而是輸出到了dist/css
下,所以css 文件就會(huì)去dist/css/img/1.png
去拿圖片绊汹,但是圖片卻位于dist/img/1.png
稽屏,這就最終導(dǎo)致了 css文件找不到圖片。
配置文件復(fù)制圖片是相對(duì)于 webpack 出口路徑的 西乖, css文件引用圖片是相對(duì)于css文件所在路徑的狐榔,如果這兩個(gè)路徑相同 也就是 webpack出口路徑 = css文件所在路徑
那么 很幸運(yùn) ,你的圖片是可以找到的浴栽。但是一般情況下是不同的荒叼,我們習(xí)慣于 將出口路徑 定為dist/
然后將css文件輸出到 'dist/css/' ,最終導(dǎo)致了引用不到圖片的結(jié)果典鸡。
至此原因分析完畢被廓。
解決方法:
在配置項(xiàng)內(nèi)加入 publicPath 屬性,設(shè)置為部署時(shí)的絕對(duì)路徑
比如所 以后你的頁(yè)面 會(huì)通過(guò)如下url方式讓用戶訪問(wèn)萝玷,所有前端文件都放置于
http://localhost:63342/url-loader-test/dist/
那么pubilcPath的 值就應(yīng)該是 '/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/" //該地址不是唯一的蜓斧,根據(jù)你的代碼實(shí)際路由地址進(jìn)行修改
}
},
這樣做的原因是仓蛆,webpack打包時(shí),還會(huì)將圖片復(fù)制到 dist/img/1.png
挎春,但是他會(huì)把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*/
這時(shí)css文件中的url 地址就變成了一個(gè)絕對(duì) 路由。
至此直奋,問(wèn)題解決能庆。