webpack之引入圖片的實(shí)現(xiàn)及問(wèn)題
前言:
本文演示了
- webpack如何在css文件中引入圖片;
- webpack如何在html中引入圖片;
需要安裝配置的loader: file-loader;
為何要使用file-loader:
如果我們希望在頁(yè)面引入圖片(包括img的src和background的url)。當(dāng)我們基于webpack進(jìn)行開(kāi)發(fā)時(shí),引入圖片會(huì)遇到一些問(wèn)題。
其中一個(gè)就是引用路徑的問(wèn)題。拿background樣式用url引入背景圖來(lái)說(shuō),我們都知道,webpack最終會(huì)將各個(gè)模塊打包成一個(gè)文件,因此我們樣式中的url路徑是相對(duì)入口html頁(yè)面的,而不是相對(duì)于原始css文件所在的路徑的。這就會(huì)導(dǎo)致圖片引入失敗。這個(gè)問(wèn)題是用file-loader解決的,file-loader可以解析項(xiàng)目中的url引入(不僅限于css),根據(jù)我們的配置,將圖片拷貝到相應(yīng)的路徑,再根據(jù)我們的配置,修改打包后文件引用路徑,使之指向正確的文件。
安裝file-loader
$ npm i -D file-loader
package.json目前配置:
配置webpack.config.js
在common下新增img文件夾,并添加圖片dog.jpeg。
我目前用的項(xiàng)目目錄:
示例一、在css中引入我們的圖片
編寫(xiě)main.css
在我們的app.js中引入main.css
執(zhí)行 npm run build構(gòu)建項(xiàng)目。
示例二、在html中引入圖片:重新編輯我們的app.js
執(zhí)行 npm run build構(gòu)建項(xiàng)目。
PS:webpack和圖片引入的一些問(wèn)題
問(wèn)題描述
- 需要使用<img>標(biāo)簽引入多個(gè)圖片
- 理想方案是將圖片的相關(guān)信息(圖片文字,圖片相對(duì)路徑)整合到一個(gè)數(shù)組imageList
- 然后對(duì)imageList做一個(gè)map render出圖片列表
const imageList = [ {id:1,info:'中國(guó)銀行',uri:'./assets/1.jpg'}, {id:2,info:'中國(guó)農(nóng)業(yè)銀行',uri:'./assets/2.jpg'}, {id:3,info:'中國(guó)建設(shè)銀行',uri:'./assets/3.jpg'} ] imageList.map((img)=>{ return ( <div> {img.info} <img src={img.uri} /> </div> ) })
但是這樣做導(dǎo)致了圖片無(wú)法找到
發(fā)現(xiàn)請(qǐng)求圖片路徑出現(xiàn)了問(wèn)題:所有圖片請(qǐng)求的路徑變成了當(dāng)前的url拼接uri
換成import image from './assets/1.jpg'將image給src就可以拿到圖片
發(fā)現(xiàn)這是webpack引入圖片的方式
問(wèn)題原因
Q1:這兩種方式的區(qū)別?
A2:主要是資源路徑的不同
- 賦給src相對(duì)路徑:導(dǎo)致資源請(qǐng)求的路徑變成:當(dāng)前url+src的值
- 賦給src import的文件:首先使用import可以返回一個(gè)字符串這個(gè)字符串是文件被打包之后(在靜態(tài)目錄下)的絕對(duì)路徑。因此當(dāng)前請(qǐng)求圖片的路徑就會(huì)變成:端口號(hào)+import的值
最后請(qǐng)求圖片的路徑很好解釋?zhuān)?/p>
- 如果src的值以slash開(kāi)頭那么會(huì)被認(rèn)為是以靜態(tài)文件為根目錄的絕對(duì)路徑
- 如果src的值不以slash開(kāi)頭那么會(huì)被認(rèn)為是當(dāng)前路徑的相對(duì)路徑
總結(jié)為:靜態(tài)服務(wù)器可以被當(dāng)做文件系統(tǒng)看待,這些uri就是文件路徑
Q2:圖片是如何被webpack打包的?
A2: 僅對(duì)于圖片的import:
打包時(shí)機(jī):在項(xiàng)目中的圖片并不是都會(huì)被打包的,經(jīng)過(guò)嘗試發(fā)現(xiàn)通過(guò)import或者background:url(image path)引入的圖片才會(huì)被打包
打包位置:通過(guò)對(duì)file-loader的設(shè)置
{ test: /\.(jpg|png|svg|pdf)$/, exclude: /font.*\.svg$/, loader: 'file-loader?name=[path][name].[hash].[ext]' } //根據(jù)這樣的設(shè)置,webpack會(huì)將所有**使用到的圖片全部加載到當(dāng)前path并且名字不變但是加上.hash.后綴**
Q3: img src的值可以是什么?background:url的值又可以是什么?
A3:
img src:
- 路徑(url)
- require(或者import的值)
- data url(base64)
background:url:
- 路徑(相對(duì))
- data url(base64)
Q4:為什么在css中使用background-url()可以使用圖片的相對(duì)路徑但是在js文件中就不能使用相對(duì)路徑賦值給src?
A4: 首先先說(shuō)明我發(fā)現(xiàn)的區(qū)別
- src:會(huì)發(fā)請(qǐng)求,請(qǐng)求靜態(tài)的外部文件資源(只要是src不論值是什么(除base64)都會(huì)發(fā)送請(qǐng)求)
- css background:不會(huì)發(fā)送請(qǐng)求
webpack對(duì)他們的處理方式也完全不同:
- - src:url :不會(huì)被webpack處理
- - src:require():會(huì)被webpack處理
- - background:url:會(huì)被webpack處理
總結(jié):使用import或者require或者background都會(huì)被webpack的file-loader當(dāng)做依賴(lài)模塊處理:
- - 打包的時(shí)候執(zhí)行到引入部分(import。。。)
- - 將對(duì)應(yīng)的靜態(tài)文件打包到配置好的位置
- - 生成打包后的絕對(duì)路徑賦值給引入部分
Q5:客戶(hù)端圖片引入的方式有幾種?他們分別有什么不同的原理?
A5:所謂客戶(hù)端圖片:就是不想通過(guò)http請(qǐng)求的方式獲取的圖片
- 通過(guò)background:url('./****')
- 通過(guò)background:url(圖片base64)
- 通過(guò)src=圖片base64
- 通過(guò)src=require('./******')
其他知識(shí)
K1:到今天終于明白file-loader的作用
當(dāng)其他模塊需要引用文件,file-loader就將對(duì)應(yīng)文件依照name屬性要求的文件路徑和文件名進(jìn)行打包。通過(guò)計(jì)算文件大小,小于limit的值,就將文件轉(zhuǎn)成base64賦給需要這些文件的位置,大于limit的值就將文件的打包后路徑賦給需要這些文件的位置
我的疑問(wèn):
網(wǎng)上有~說(shuō)是作為src值的開(kāi)頭可以將這部分的請(qǐng)求作為依賴(lài)模塊處理但是我沒(méi)有嘗試成功
我的解決方案
- 由于我還不知道該如何給background-url編程循環(huán)引入圖片所以我決定采用:
- 因此我采用編寫(xiě)一個(gè)對(duì)象數(shù)組,對(duì)對(duì)象數(shù)組進(jìn)行map,return<img src={require(bank.img+'')}>
const BANK_LIST = [ {name: '中國(guó)銀行', img: './assets/bank-logo-6.png', id: 1}, {name: '中國(guó)建設(shè)銀行', img: './assets/bank-logo-7.png', id: 2}, {name: '興業(yè)銀行', img: './assets/bank-logo-8.png', id: 3} ] BANK_LIST.map((bank)=>{ return ( <img src={require(bank.img+'')} /> ) })
我的另外一種解決方案(由于項(xiàng)目中的eslint要求不支持動(dòng)態(tài)引入文件)
使用webpack帶的require.context('pathToDirectory')他可以循環(huán)的將一個(gè)目錄下的所有文件引入
const BANK_LIST = { './bank-logo-6.png': {name: '中國(guó)銀行', id: 1}, './bank-logo-7.png': {name: '中國(guó)建設(shè)銀行', id: 2}, './bank-logo-8.png': {name: '興業(yè)銀行', id: 3} } const pathToImages = require.context('./assets'); const originalBankList = pathToImages.keys().map((key) => { return Object.assign({}, BANK_LIST[key], {url: pathToImages(key)}) }); //這時(shí)候originalBankList的每一項(xiàng)會(huì)變成 {name: '中國(guó)銀行', id: 1,url: "/app/src/containers/WisePort/CheckoutCounterContai…/bank-logo-1.9f949c516315756e18c0cb7d572f4d2c.png"'}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
微信小程序?qū)崿F(xiàn)頁(yè)面導(dǎo)航與傳參功能詳解
這篇文章主要為大家詳細(xì)介紹一下微信小程序?qū)崿F(xiàn)頁(yè)面導(dǎo)航的幾種方法以及幫助大家掌握微信小程序如何進(jìn)行傳遞參數(shù),感興趣的朋友可以了解一下2022-08-08詳解JavaScript數(shù)組過(guò)濾相同元素的5種方法
本篇文章主要介紹了詳解JavaScript數(shù)組過(guò)濾相同元素的5種方法,詳細(xì)的介紹了5種實(shí)用方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05JS動(dòng)態(tài)添加選項(xiàng)案例分析
這篇文章主要介紹了JS動(dòng)態(tài)添加選項(xiàng)的方法,結(jié)合實(shí)例形式分析了javascript針對(duì)頁(yè)面元素動(dòng)態(tài)操作的相關(guān)技巧,需要的朋友可以參考下2016-10-10BootStrap Select清除選中的狀態(tài)恢復(fù)默認(rèn)狀態(tài)
PC端項(xiàng)目中經(jīng)常會(huì)出現(xiàn)大量的數(shù)據(jù)列表頁(yè)面,涉及到下拉框選擇篩選條件;當(dāng)時(shí)用到bootstrap-select下拉框時(shí)該如何點(diǎn)擊重置按鈕就清除下拉框的選中狀態(tài)呢?下面通過(guò)本文給大家介紹下,需要的的朋友參考下吧2017-06-06小程序rich-text組件如何改變內(nèi)部img圖片樣式的方法
這篇文章主要介紹了小程序rich-text組件如何改變內(nèi)部img圖片樣式的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05微信小程序?qū)Ш綑诟S滑動(dòng)效果的實(shí)現(xiàn)代碼
這篇文章主要介紹了小程序?qū)Ш綑诟S滑動(dòng)效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-05-05createObjectURL方法實(shí)現(xiàn)本地圖片預(yù)覽
這篇文章主要為大家詳細(xì)介紹了createObjectURL方法實(shí)現(xiàn)本地圖片預(yù)覽,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09javascript 的變量、作用域和內(nèi)存問(wèn)題
這篇文章主要介紹了javascript 的變量、作用域和內(nèi)存問(wèn)題的相關(guān)資料,需要的朋友可以參考下2017-04-04微信小程序--特定區(qū)域滾動(dòng)到頂部時(shí)固定的方法
這篇文章主要介紹了微信小程序--特定區(qū)域滾動(dòng)到頂部時(shí)固定的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04