根据Vite文档,可以将文件作为原始数据字符串导入。
在一个精简的项目中,我不仅需要使用 URL,还需要使用整个图像数据。 因此,我尝试
import image from "@/assets/image.png?raw"
。
然而,无论我尝试什么,我都无法将其转换为Uint8Array
。我尝试过使用 string.charCodeAt(0)
、string.codePointAt(0)
和各种其他东西。
我希望第一个字节是 137, 80, 78, 71, 13, 10, 26, 10
,因为那是 PNG header,但它总是返回为 253, 80, 78, 71, 13, 10, 26, 10
。这些差异贯穿整个字符串。
我不知道它是什么编码,因此不知道如何将其再次解码为图像数据。我之前尝试过使用
fetch()
,但由于我的来源使用 Basic-Auth
,这也不起作用(凭据会因用户而异,我想避免让他们在其他地方再次输入它 - 我使用 https://user:[email protected]
作为 URL 符号)。
import image from "@/assets/image.png?raw";
let data = Uint8Array.from([..image].map(x => x.codePointAt(0)));
console.log(data);
// [253, 80, 78, 71, 13, 10, 26, 10, ...]
如何在不使用 fetch 之类的情况下将实际图像数据获取到我的脚本中? 格式几乎可以是任何东西,我将它用作
Uint8Array
和 base64
字符串,并且可以在两者之间进行转换。我还可以从 Blob
/ File
进行转换。
原始加载器似乎不适合二进制数据。当我尝试时,我最终在数据中出现了替换字符 (
�
)。
您可以轻松编写自己的插件,根据需要对图像进行编码,例如作为十六进制字符串:
/** @type {import('vite').Plugin} */
const hexLoader = {
name: 'hex-loader',
transform(code, id) {
const [path, query] = id.split('?');
if (query != 'raw-hex')
return null;
const data = fs.readFileSync(path);
const hex = data.toString('hex');
return `export default '${hex}';`;
}
};
可以在vite配置中添加,例如
const config = {
plugins: [hexLoader, sveltekit()],
// ...
}
然后您可以使用
path/file.png?raw-hex
导入并转换数据。
如何正确导入资源有点令人困惑,但我相信使用 url 是正确的选择。如此处所述 https://vitejs.dev/guide/assets.html#importing-asset-as-url 这些将内联为八位字节流或静态资产,名称中的哈希值会发生变化,允许使用长缓存过期时间。
虽然我也尝试使用如上所示的十六进制字符串,但我发现它使导入的二进制文件的大小增加了一倍。所以我现在使用:
import binUrl from './file.bin?url'
...
const bin = new Uint8Array(await (await fetch(binUrl)).arrayBuffer())
...