自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

不是吧?強(qiáng)大的 Vite 居然不支持內(nèi) SVG 轉(zhuǎn) Base64 內(nèi)嵌?

開發(fā) 前端
這次經(jīng)歷,我認(rèn)識到 一個(gè)大型的開源項(xiàng)目的維護(hù)者,對單元測試是非??粗氐?,因?yàn)樗绊懼f萬的開發(fā)者,必須保證在絕大多數(shù)情況下能正確運(yùn)行。然后就是 Vite 維護(hù)者 非常注重性能,畢竟是一個(gè)很重要的構(gòu)建工具。SVG 是可以 Base64 的,實(shí)現(xiàn)邏輯也很簡單,和其他圖形走一樣的邏輯。

大家好,我是前端西瓜哥。

誒喲喂,SVG 怎么沒內(nèi)嵌?

最近啊,西瓜哥我用 vite 去給一個(gè)項(xiàng)目構(gòu)建(vite build)一個(gè)應(yīng)用。打包結(jié)果是一個(gè) html 和一些加了哈希的資源。

然后打包出來的文件一看,發(fā)現(xiàn)居然有好幾個(gè) 1 Kb 以下的 SVG  文件。

我搜了下源碼,這些 SVG 是這樣被使用的:

<img src="./image/somIcon.svg">

不對呀,理論上小于 4 Kb 的靜態(tài)資源,是會轉(zhuǎn)成 base64 編碼字符串,嵌入到其他資源中。

較小的資源體積小于 assetsInlineLimit 選項(xiàng)值 則會被內(nèi)聯(lián)為 base64 data URL。

build.assetsInlineLimit 默認(rèn)值為 4096 (4kb)。

我發(fā)現(xiàn)使用庫模式(打包成 index.es.js,使用該模式需要設(shè)置 build.lib 配置)時(shí),是不會出現(xiàn) SVG 文件的。

如果你指定了 build.lib,那么 build.assetsInlineLimit 將被忽略,無論文件大小或是否為 Git LFS 占位符,資源都會被內(nèi)聯(lián)。

所以一開始我以為我的配置設(shè)置的有問題,因?yàn)閹炷J經(jīng)]問題了。

我折騰了大半天,檢查配置,查文檔,assetsInlineLimit 給你加到 999999,安裝其他版本的包,給引入的文件末尾加上 ?inline。各種嘗試,都沒用。

后來我用最新版的 vite 構(gòu)建了一個(gè)新的 Vue 項(xiàng)目。

發(fā)現(xiàn)它這個(gè)官方給的 demo 打包出來的文件 SVG 都沒做內(nèi)聯(lián)。

好家伙,我尋思 vite 本身就不支持 SVG 轉(zhuǎn) base64 編碼內(nèi)嵌。

設(shè)計(jì)如此,本就不支持 SVG 轉(zhuǎn) Base64

走,去翻翻 vite 的 issue,然后找到了一個(gè) 3 年前的  issue,編號 1204。

這個(gè) issue 標(biāo)記為 enhancement,即它是一個(gè)增強(qiáng)功能,并不是 bug。

此外可以看到有兩個(gè) PR 是要解決這個(gè) issue 的。

一個(gè) PR 被關(guān)閉了,一個(gè) PR 是打開著。我們?nèi)タ纯础?/p>

先看看被關(guān)閉的那個(gè),PR 編號是 1716,是 vite 成員提的 PR。

他說他不贊成 SVG 轉(zhuǎn)成 Base64 嵌入到 HTML,SVG 是個(gè)文本類的特殊圖片格式,不是二進(jìn)制,沒必要再轉(zhuǎn)一層 Base64,導(dǎo)致體積變大。

因?yàn)?Base64 需要用 4 個(gè)字符表達(dá)原來文本的 3 個(gè)字節(jié),會增大 33~36% 的體積。

即希望結(jié)果是:

<img src='data:image/svg+xml;utf8,<svg ... > ... </svg>'>

而不是:

<img src="data:image/svg+xml;base64,PHN2ZyB4bWxu...c3ZnPg==">

雖然不打算轉(zhuǎn) Base64,但還是可以轉(zhuǎn) utf8 格式的 Data URL 的,一樣可以實(shí)現(xiàn)內(nèi)嵌的效果,而且體積更小,于是提了這個(gè) PR。

這個(gè) PR 是有問題的,有些情況沒處理,比如轉(zhuǎn)義,去掉 svg fragments 等。

然而過了一個(gè)月,這個(gè) PR 還是沒進(jìn)展,說明 優(yōu)先級并不高。

此時(shí)一位路過的野生程序員說他來搭把手。

于是這個(gè) PR 關(guān)閉了,這位老哥創(chuàng)建了一個(gè)新的 PR。

這個(gè) PR 一直就掛在那

加油啊,路過的程序員老哥。你是我們?nèi)迦说南M ?/p>

看看 PR。

兩年前的 PR,至今仍是 Open 狀態(tài)。

哦豁,涼了。

發(fā)生甚么事了?我瞅瞅。

看下 PR 的內(nèi)容。引入了一個(gè) mini-svg-data-uri 第三方包,來做 SVG 轉(zhuǎn) DataUrl,改了一些判斷條件,因?yàn)楹推胀ㄙY源直接走轉(zhuǎn) base64 不同,SVG 是要直接用原來的文本內(nèi)容的。改了了幾個(gè)測試用例。

看著不少 review 和討論,看著應(yīng)該還行,有幾個(gè) vite 成員 approved 了。

最后時(shí)需要有人手動測試是否處理好了 SVG Segment 的情況。此時(shí)提 PR 的老哥不見了。

SVG Segment 是 SVG 的一個(gè)比較特殊的用法,大概是這樣(來自 MDN)。

對于一個(gè) SVG,我們可以用 view 標(biāo)簽指定某種情況下特定的 viewBox 視口范圍。

<svg viewBox="0 0 300 100" width="300" height="100"
      xmlns="http://www.w3.org/2000/svg">

  <view id="one" viewBox="0 0 100 100" />
  <circle cx="50" cy="50" r="40" fill="red" />

  <view id="two" viewBox="100 0 100 100" />
  <circle cx="150" cy="50" r="40" fill="green" />

  <view id="three" viewBox="200 0 100 100" />
  <circle cx="250" cy="50" r="40" fill="blue" />
</svg>

然后在使用的時(shí)候通過 icon.svg#<id>  指定 id,來修改 SVG 最終展示的 viewBox。

<!-- 正常視口 -->
<img src="example.svg" alt="three circles" width="300" height="100" />


<!-- 視口切換到綠色圓的位置 -->
<img src="example.svg#three" alt="blue circle" width="100" height="100" />

效果:

回到  PR。

好久,后面有人幫著測試了,發(fā)現(xiàn)有問題。然后就,沒有然后了,此外還有因?yàn)殚L期沒合入出現(xiàn)的合并沖突。

湊合著用吧

啊這。

我 fork 了 vite 項(xiàng)目,把這位老哥的修改應(yīng)用到最新版本上,然后 build 了一下,并拿去構(gòu)建我的一個(gè) demo 項(xiàng)目,結(jié)果 SVG 成功變成了 Base64。

然后我運(yùn)行測試相關(guān)的命令,各種不對。

因?yàn)橛行┰瓉磙D(zhuǎn)換為正常 url 的,現(xiàn)在會轉(zhuǎn)成 base64,就匹配不上了。我還發(fā)現(xiàn) css url 的邏輯還有點(diǎn)問題,拿到了一個(gè)錯(cuò)誤的 none 值。

誒,感覺要提 PR 的話,要修正原來的測試用例,并補(bǔ)充一些新的測試用例,還要處理 css 的情況。行吧,以后再看看。

回到我一開始的需求,行,你不給我轉(zhuǎn) Base64 是吧?我通過 ?raw 直接拿到 SVG 文本內(nèi)容,給你動態(tài)轉(zhuǎn)成 Base64。

import iconSvg from './image/someIcon.svg?raw'; // 這個(gè)會拿到 "<svg ...>...</svg>"

const toSVGDataUrl = (str: string) => {
  const base64 = btoa(str);
  return `data:image/svg+xml;base64,${base64}`;
};

<img :src="toSVGDataUrl(iconSvg)" />

還行(又不是不能用)。

結(jié)尾

這次經(jīng)歷,我認(rèn)識到 一個(gè)大型的開源項(xiàng)目的維護(hù)者,對單元測試是非??粗氐?,因?yàn)樗绊懼f萬的開發(fā)者,必須保證在絕大多數(shù)情況下能正確運(yùn)行。

突然想起之前 VSCode 我更新了最新版本,結(jié)果運(yùn)行一段時(shí)間就會報(bào)錯(cuò)需要重啟。

然后就是 vite 維護(hù)者 非常注重性能,畢竟是一個(gè)很重要的構(gòu)建工具。SVG 是可以 Base64 的,實(shí)現(xiàn)邏輯也很簡單,和其他圖形走一樣的邏輯。

但 SVG 可以直接用原本的文本數(shù)據(jù),更小,有優(yōu)化空間。因?yàn)轶w積可以優(yōu)化,所以維護(hù)者就寧缺毋濫,寧可丟掉這個(gè)功能。

要是我,我可能就先圖省事,直接支持 Base64 了,然后有機(jī)會再優(yōu)化(通常不了了之)。

然后是優(yōu)先級,優(yōu)先級不高,維護(hù)者就是不會主動去實(shí)現(xiàn)。

此時(shí)就需要社區(qū)的力量了,如果你很需要某個(gè)功能,就要積極提 PR,積極討論并主動推進(jìn),否則可能像這個(gè) PR 一樣,半途而廢。

責(zé)任編輯:姜華 來源: 前端西瓜哥
相關(guān)推薦

2023-11-07 08:35:26

2020-09-14 06:52:42

Java對象代碼

2012-05-16 19:16:10

iPhone 5

2016-12-13 13:50:06

JAVA轉(zhuǎn)換Base64

2011-12-09 20:28:50

2021-02-05 05:26:33

字節(jié)ASCII控制

2014-02-20 10:28:28

JavaScriptBase64

2025-02-11 00:00:10

Base64編碼二進(jìn)制

2021-09-07 08:59:09

編碼Base64解碼

2021-08-26 05:27:08

Base64 字節(jié)流算法

2010-03-03 16:14:05

Python base

2024-07-31 10:22:49

Go語言編碼

2021-03-05 09:10:19

base64編碼

2020-07-02 10:30:52

iPhone蘋果北斗

2025-04-23 00:04:00

2023-11-02 08:25:25

組件ReactUI

2024-02-28 23:07:42

GolangBase64編碼

2022-10-29 19:58:09

Base64Bashshell

2025-01-14 12:18:06

Base64加解密字符

2021-04-20 19:23:07

語法switch-casePython
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號