不是吧?强大的 vite 居然不支持内 SVG 转 Base64 内嵌?

news2024/10/7 14:27:28

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

诶哟喂,SVG 怎么没内嵌?

最近啊,西瓜哥我用 vite 去给一个项目构建(vite build)一个应用。打包结果是一个 html 和一些加了哈希的资源。

然后打包出来的文件一看,发现居然有好几个 1 Kb 以下的 SVG 文件。

我搜了下,这些 SVG 是这样被使用的:

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

不对呀,理论上小于 4 Kb 的静态资源,是会转成 base64 编码字符串,嵌入到其他资源中。

较小的资源体积小于 assetsInlineLimit 选项值 则会被内联为 base64 data URL。

build.assetsInlineLimit 默认值为 4096 (4kb)。

我发现使用库模式(打包成 index.es.js,使用该模式需要设置 build.lib 配置)时,是不会出现 SVG 文件的。

如果你指定了 build.lib,那么 build.assetsInlineLimit 将被忽略,无论文件大小或是否为 Git LFS 占位符,资源都会被内联。

所以一开始我以为我的配置设置的有问题,因为库模式没问题了。

我折腾了大半天,检查配置,查文档,assetsInlineLimit 给你加到 999999,安装其他版本的包,给引入的文件末尾加上 ?inline。各种尝试,都没用。

后来我用最新版的 vite 构建了一个新的 Vue 项目。

发现它这个官方给的 demo 打包出来的文件 SVG 都没做内联。

好家伙,我寻思 vite 本身就不支持 SVG 转 base64 编码内嵌。

设计如此,本就不支持 SVG 转 Base64

走,去翻翻 vite 的 issue,然后找到了一个 3 年前的 issue,编号 1204。

这个 issue 标记为 enhancement,即它是一个增强功能,并不是 bug。

此外可以看到有两个 PR 是要解决这个 issue 的。

一个 PR 被关闭了,一个 PR 是打开着。我们去看看。

先看看被关闭的那个,PR 编号是 1716,是 vite 成员提的 PR。

他说他不赞成 SVG 转成 Base64 嵌入到 HTML,SVG 是个文本类的特殊图片格式,不是二进制,没必要再转一层 Base64,导致体积变大。

因为 Base64 需要用 4 个字符表达原来文本的 3 个字节,会增大 33~36% 的体积。

即希望结果是:

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

而不是:

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

虽然不打算转 Base64,但还是可以转 utf8 格式的 Data URL 的,一样可以实现内嵌的效果,而且体积更小,于是提了这个 PR。

这个 PR 是有问题的,有些情况没处理,比如转义,去掉 svg fragments 等。

然而过了一个月,这个 PR 还是没进展,说明 优先级并不高

此时一位路过的野生程序员说他来搭把手。

于是这个 PR 关闭了,这位老哥创建了一个新的 PR。

这个 PR 一直就挂在那

加油啊,路过的程序员老哥。你是我们全村人的希望啊。

看看 PR。

两年前的 PR,至今仍是 Open 状态。

哦豁,凉了。

发生甚么事了?我瞅瞅。

看下 PR 的内容。引入了一个 mini-svg-data-uri 第三方包,来做 SVG 转 DataUrl,改了一些判断条件,因为和普通资源直接走转 base64 不同,SVG 是要直接用原来的文本内容的。改了了几个测试用例。

看着不少 review 和讨论,看着应该还行,有几个 vite 成员 approved 了。

最后时需要有人手动测试是否处理好了 SVG Segment 的情况。此时提 PR 的老哥不见了。

SVG Segment 是 SVG 的一个比较特殊的用法,大概是这样(来自 MDN)。

对于一个 SVG,我们可以用 view 标签指定某种情况下特定的 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>

然后在使用的时候通过 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。

好久,后面有人帮着测试了,发现有问题。然后就,没有然后了,此外还有因为长期没合入出现的合并冲突。

凑合着用吧

啊这。

我 fork 了 vite 项目,把这位老哥的修改应用到最新版本上,然后 build 了一下,并拿去构建我的一个 demo 项目,结果 SVG 成功变成了 Base64。

然后我运行测试相关的命令,各种不对。

因为有些原来转换为正常 url 的,现在会转成 base64,就匹配不上了。我还发现 css url 的逻辑还有点问题,拿到了一个错误的 none 值。

诶,感觉要提 PR 的话,要修正原来的测试用例,并补充一些新的测试用例,还要处理 css 的情况。行吧,以后再看看。

回到我一开始的需求,行,你不给我转 Base64 是吧?我通过 ?raw 直接拿到 SVG 文本内容,给你动态转成 Base64。

import iconSvg from './image/someIcon.svg?raw'; // 这个会拿到 "<svg ...>...</svg>"

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

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

还行(又不是不能用)。

结尾

这次经历,我认识到 一个大型的开源项目的维护者,对单元测试是非常看重的,因为它影响着千千万万的开发者,必须保证在绝大多数情况下能正确运行。

突然想起之前 VSCode 我更新了最新版本,结果运行一段时间就会报错需要重启。

然后就是 vite 维护者 非常注重性能,毕竟是一个很重要的构建工具。SVG 是可以 Base64 的,实现逻辑也很简单,和其他图形走一样的逻辑。

但 SVG 可以直接用原本的文本数据,更小,有优化空间。因为体积可以优化,所以维护者就宁缺毋滥,宁可丢掉这个功能。

要是我,我可能就先图省事,直接支持 Base64 了,然后有机会再优化(通常不了了之)。

然后是优先级,优先级不高,维护者就是不会主动去实现

此时就需要社区的力量了,如果你很需要某个功能,就要积极提 PR,积极讨论并主动推进,否则可能像这个 PR 一样,半途而废。

我是前端西瓜哥,关注我,学习更多前端知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/767634.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringCloud学习路线(3)—— Eureka注册中心

一、导引 服务调用出现的问题 服务调用采取的请求地址是静态的&#xff0c;当我们使用服务集群时&#xff0c;很容易造成只能调用固定的微服务上的接口。多个提供者&#xff0c;消费者的使用对象无法确定消费者无法得知提供者的状态 二、Eureka注册中心 &#xff08;一&…

加水印用什么软件你知道吗?告诉你加水印的app哪个好用吧

笑笑是一个热爱生活的女孩&#xff0c;她经常会随手拍下生活的瞬间&#xff0c;并且在社交媒体上分享自己的开心时刻。然而&#xff0c;最近她发现自己的照片被未经授权地使用在其他网站和博客上。这让她感到非常生气。为了保护自己的作品权益&#xff0c;她决定寻找一个好用的…

vue3 h函数使用图文教程

序&#xff1a; 1、官方文档地址》渲染函数 & JSX | Vue.js 2、博主微信公众号&#xff1a;“程序员野区”&#xff0c;关注公众号回复“加群&#xff0c;可以进到博主微信群 正文&#xff1a; 别恐惧啊&#xff0c;别一看官方api那边标注的 是进阶api就跳过去&#xff0c…

1ll大学学生信息管理系统系统_学院管理_查询新增或修改删除标准接口_

目录 修订版本 1. 目的 2. 阅读人员 3. 参考文档 ll大学学生信息管理系统系统_学院管理_查询新增或修改删除标准接口 4.1 接口概述 4.2 接口名称 4.3查询学院信息接口标准 4.4新增学院信息接口标准 4.5修改学院信息接口标准 学生信息管理系统系统_学院管理_查询新增或…

【unity细节】分不清楚__世界坐标,自身坐标,Vector3,transform和translate?

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;unity细节和bug ⭐世界坐标系transform和自身坐标Trasform.local和Vector3⭐ 文章目录 ⭐世界坐标…

__builtin_return_address函数

文章目录 一、gcc 内置函数二、__builtin_return_address2.1 简介2.2 代码示例 三、查看函数调用参考资料 一、gcc 内置函数 GCC 内置函数是指 GCC 编译器内置的一些函数&#xff0c;这些函数可以用于实现一些常用的操作&#xff0c;如数学运算、字符串处理、内存管理、调试等…

如何创作小红书化妆品文案,技巧分析!

小红书拥有众多女性用户群。美妆自然成为里面最大的板块&#xff0c;所以不管是护肤品牌&#xff0c;还是相关达人都会进行化妆品类的文案创作。今天从两个方案来探讨下如何创作小红书化妆品文案&#xff0c;技巧分析&#xff01; 一、对品牌输出文案的重点 1. 强调产品特点 向…

牛客周赛 Round 3

游游的7的倍数 思路分析 添加一个数让其为7的倍数。倍数&#xff0c;每7个中必有一个是7的倍数&#xff0c;在末尾添加一个数即可.遍历0-6&#xff0c;满足既可。 时间复杂度 O&#xff08;1&#xff09; 代码 #include<bits/stdc.h> using namespace std; using ll…

毫秒级的 Unix 时间戳,将其转换为日期时间格式,报错,“将 expression 转换为数据类型 int 时出现算术溢出错误”

如果您有一个时间戳值为 1689217823000&#xff0c;表示毫秒级的 Unix 时间戳&#xff0c;您可以将其转换为日期时间格式。在 SQL Server 中&#xff0c;可以使用 DATEADD 和 CONVERT 函数来进行转换。 以下是将该时间戳值转换为日期时间格式的步骤&#xff1a; DECLARE timest…

从零开始学习 Java:简单易懂的入门指南(一)

Java基础语法 1. 人机交互1.1 什么是cmd&#xff1f;1.2 如何打开CMD窗口&#xff1f;1.3 常用CMD命令1.4 CMD练习1.5 环境变量 2. Java概述1.1 Java是什么&#xff1f;1.2下载和安装1.2.1 下载1.2.2 安装1.2.3 JDK的安装目录介绍 1.3 HelloWorld小案例1.3.1 Java程序开发运行…

【矩阵的基本操作】——MatLab基础

目录索引 矩阵的基本操作&#xff1a;转置&#xff1a;矩阵的拼接&#xff1a;*横拼&#xff1a;**竖拼&#xff1a;* 矩阵的索引&#xff1a;取元素&#xff1a;*end():* 取区域&#xff1a;逻辑判断&#xff1a;逻辑取值&#xff1a;find()&#xff1a; 矩阵的基本操作&#…

基于net core2.2的redis秒杀+数据持久化+数据恢复系列(2)

第一篇我们总结了秒杀的整个流程&#xff0c;本篇我们详细介绍下redis的秒杀实现&#xff0c;基于.net core2.2开发。 首先&#xff0c;需要安装redis&#xff0c;因为我在本地测试的&#xff0c;所以安装的windows版本的redis。redis分为服务端和客户端&#xff0c;这个redis…

了解Azido TAT,使用铜催化的叠氮化物反应修饰Tat肽,以下内容查看详细信息!

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ 【产品描述】 Azido-TAT中Tat肽已被证明具有优异的细胞穿透性&#xff0c;可以增强对特异性靶向疾病的诊断和 寡核苷酸的吸收。寡核苷酸通过点击化学与Tat&#xff08;一种生物学上重要的细胞穿透肽&#xff09;的共价连接…

❤ npm install 时报Error: spawn git ENOENT

❤ npm install 时报Error: spawn git ENOENT 原因&#xff1a; 主要是因为由于 git 的环境变量未设置导致&#xff0c;所以安装一下git 的环境变量就O了&#xff0c;步骤如下&#xff1a; 设置 >> 系统 >> 高级系统设置 >> 高级 >> 环境变量 >&g…

编写软件测试用例的方法,你知道多少种

1、等价类划分法 适用场景&#xff1a; 有数据输入的地方&#xff0c;就可以使用等价类划分法。如&#xff1a;输入框 测试思想&#xff1a; 从大量数据中划分范围&#xff08;等价类&#xff09;&#xff0c;然后从每个范围中挑选代表数据&#xff0c;这些代表数据要能反应…

株洲科能冲刺上市:计划募资约6亿元,实控人为赵科峰、唐燕夫妇

7月17日&#xff0c;上海证券交易所披露的信息显示&#xff0c;已对株洲科能新材料股份有限公司&#xff08;下称“株洲科能”&#xff09;发出问询函。据贝多财经了解&#xff0c;株洲科能于2023年6月21日递交招股书&#xff0c;准备在科创板上市。 本次冲刺科创板上市&#x…

springboot+mybatis-plus实现自动建表

好长时间没输出了&#xff0c;最近工作上也是太多事&#xff0c;领导动不动就拍脑门&#xff0c;那叫一个酸爽~ 工作能力的提现不但是技术或解决问题的能力上&#xff0c;还体现在要能立刻满足领导的各种需求&#xff0c;不管是哪方面的需求&#xff0c;这样才能够拍上马屁&…

IDDR和ODDR

IDDR D&#xff1a;输入双倍速率数据&#xff08;IOB输入&#xff0c;且数据在时钟的上升沿和下降沿都会发生切换&#xff0c;即一个时钟周期发送2bit数据&#xff09; CE&#xff1a;时钟使能信号&#xff08;高有效&#xff09; C&#xff1a;时钟信号 S&#xff0c;R&#x…

STM32F4_串口 IAP

目录 前言 1. IAP简介 2. APP程序起始地址设置方法 3. 中断向量表的偏移量设置 4. 如何在MDK中生成 .BIN 文件 5. APP程序生成步骤 前言 IAP&#xff0c;即在应用编程。 1. IAP简介 IAP&#xff08;In Application Programming&#xff09;即 在应用编程&#xff0c;IAP…

Apache RocketMQ5.x-消息队列体验

Apache RocketMQ5.x-消息队列体验 Apache RocketMQ 是一款低延迟、高并发、高可用、高可靠的分布式消息中间件&#xff0c;由阿里开源&#xff0c;后由阿里捐赠给Apache基金会。 本次体验的目的是从技术角度验证一下在微服架构中&#xff0c;用Apache RocketMQ做为消息队列&am…