前言:
本文示範了
webpack如何在css檔案中引入圖檔;
webpack如何在html中引入圖檔;
需要安裝配置的loader: file-loader;
為何要使用file-loader:
如果我們希望在頁面引入圖檔(包括img的src和background的url)。當我們基于webpack進行開發時,引入圖檔會遇到一些問題。
其中一個就是引用路徑的問題。拿background樣式用url引入背景圖來說,我們都知道,webpack最終會将各個子產品打包成一個檔案,是以我們樣式中的url路徑是相對入口html頁面的,而不是相對于原始css檔案所在的路徑的。這就會導緻圖檔引入失敗。這個問題是用file-loader解決的,file-loader可以解析項目中的url引入(不僅限于css),根據我們的配置,将圖檔拷貝到相應的路徑,再根據我們的配置,修改打包後檔案引用路徑,使之指向正确的檔案。
安裝file-loader
$ npm i -D file-loader
package.json目前配置:
配置webpack.config.js
在common下新增img檔案夾,并添加圖檔dog.jpeg。
我目前用的項目目錄:
示例一、在css中引入我們的圖檔
編寫main.css
在我們的app.js中引入main.css
執行 npm run build建構項目。
示例二、在html中引入圖檔:重新編輯我們的app.js
執行 npm run build建構項目。
PS:webpack和圖檔引入的一些問題
問題描述
需要使用
标簽引入多個圖檔
理想方案是将圖檔的相關資訊(圖檔文字,圖檔相對路徑)整合到一個數組imageList
然後對imageList做一個map render出圖檔清單
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 (
{img.info}
)
})
但是這樣做導緻了圖檔無法找到
發現請求圖檔路徑出現了問題:所有圖檔請求的路徑變成了目前的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('./******')
其他知識
K1:到今天終于明白file-loader的作用
當其他子產品需要引用檔案,file-loader就将對應檔案依照name屬性要求的檔案路徑和檔案名進行打包。通過計算檔案大小,小于limit的值,就将檔案轉成base64賦給需要這些檔案的位置,大于limit的值就将檔案的打包後路徑賦給需要這些檔案的位置
我的疑問:
網上有~說是作為src值的開頭可以将這部分的請求作為依賴子產品處理但是我沒有嘗試成功
我的解決方案
由于我還不知道該如何給background-url程式設計循環引入圖檔是以我決定采用:
是以我采用編寫一個對象數組,對對象數組進行map,return
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 (
)
})
我的另外一種解決方案(由于項目中的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"'}
以上就是本文的全部内容,希望對大家的學習有所幫助,也希望大家多多支援腳本之家。