用 "vfsArchive" 从 ZIP 压缩包提供资源


🌐 Serving the assets from a ZIP archive with "vfsArchive"

配置时,不用列出单个 "assets",可以让 "vfsArchive" 指向一个预先构建好的 ZIP 压缩包。这个压缩包会原封不动地嵌入到可执行文件里,虚拟文件系统会提供里面的文件,并在读取时解压每个文件。当资源是可压缩的(比如 JavaScript、JSON 或其他文本)时,使用 deflate 压缩的压缩包可以大大减小生成的可执行文件的体积。

🌐 Instead of listing individual "assets", the configuration can point "vfsArchive" at a prebuilt ZIP archive. The archive is embedded into the executable as-is, and the virtual file system serves the files inside it, inflating each one when it is read. When the assets are compressible (such as JavaScript, JSON, or other text), a deflate-compressed archive can substantially reduce the size of the generated executable.

这个压缩包可以用任何 ZIP 工具创建,也可以用 node:zlib 提供的 ZIP 支持创建:

🌐 The archive can be built with any ZIP tool, or with the ZIP support in node:zlib:

import { zipFiles } from 'node:zlib';
import { createWriteStream } from 'node:fs';
import { pipeline } from 'node:stream/promises';

await pipeline(
  zipFiles([
    ['./dist/config.json', 'config.json'],
    ['./dist/data.txt', 'data/data.txt'],
  ]),
  createWriteStream('assets.zip'),
); 

挂载的文件树看起来和使用 "assets" 时一样:条目会以它们的归档名称出现在挂载点下,主脚本放在挂载点根目录,通过 __dirname 相关路径、require() 和 import 的访问保持不变。不过,sea.getAsset() 和 sea.getAssetAsBlob() 并不能提供单个文件,因为可执行文件只是嵌入了归档;要通过文件系统 API 读取文件。"vfsArchive" 需要 "useVfs": true,并且不能和 "assets" 一起使用。

🌐 The mounted file tree looks the same as with "assets": the entries appear under the mount point using their archive names, the main script is placed at the mount point root, and access through __dirname-relative paths, require(), and import is unchanged. However, sea.getAsset() and sea.getAssetAsBlob() do not serve the individual files, because the executable only embeds the archive; read the files through the file system APIs instead. "vfsArchive" requires "useVfs": true and cannot be combined with "assets".