esbuild 打包 PGlite 时 new URL() 资源解析失败如何手动提供 WASM 模块与 fsBundle?
2026/9/15 21:04:58 网站建设 项目流程

esbuild 打包 PGlite 时 new URL() 资源解析失败如何手动提供 WASM 模块与 fsBundle?

【免费下载链接】pgliteEmbeddable Postgres with real-time, reactive bindings.项目地址: https://gitcode.com/GitHub_Trending/pg/pglite

当你用 esbuild 打包一个使用 PGlite 的前端项目时,会遇到一个典型的资源解析问题:PGlite 靠new URL('./file', import.meta.url)这个写法来定位自己的 WebAssembly 模块和数据文件,而 esbuild 不支持这种模式,导致自动的文件解析开箱即用不了。这篇文章解决的就是这一个具体问题——在 esbuild 环境下,如何手动提供pgliteWasmModuleinitdbWasmModulefsBundle这三项,让 PGlite 实例正常创建,并说明如何验证它确实跑起来了。

先说清楚 PGlite 到底在用这些资源做什么。在 pglite.ts 里,创建实例时会用new URL('../release/pglite.wasm', import.meta.url)new URL('../release/initdb.wasm', import.meta.url)new URL('../release/pglite.data', import.meta.url)去定位三个文件(见 pglite.ts#L315-L338)。esbuild 不认这种 URL 写法,所以打包后这些路径就失效了。解决办法就是绕过自动解析,自己把这三样东西喂给 PGlite。

准备条件

  • 项目中已安装@electric-sql/pglitenode_modules/@electric-sql/pglite/dist/目录里能找到pglite.wasminitdb.wasmpglite.data这三个文件。
  • 你使用 esbuild 作为构建工具,且需要你的 Web 服务器能够对外提供这三个静态文件。

第一步:把三个文件复制到静态资源目录

pglite.wasminitdb.wasmpglite.datanode_modules/@electric-sql/pglite/dist/复制到你的 public/build 目录,让你的 Web 服务器能直接按路径访问到它们。

这一步只是文件搬运,不涉及安装系统工具或改动环境。复制后,这三个文件在你的站点根路径下应该能通过/pglite.wasm/initdb.wasm/pglite.data访问到。

第二步:创建实例时手动传入三个选项

在创建 PGlite 实例时,不再依赖自动解析,而是用fetch把三个资源拉下来,再作为选项传进去:

import { PGlite } from '@electric-sql/pglite' const [pgliteWasmModule, initdbWasmModule, fsBundle] = await Promise.all([ WebAssembly.compileStreaming(fetch('/pglite.wasm')), WebAssembly.compileStreaming(fetch('/initdb.wasm')), fetch('/pglite.data').then((response) => response.blob()), ]) const db = await PGlite.create({ pgliteWasmModule, initdbWasmModule, fsBundle, })

这里对应的是 interface.ts#L98-L100 中声明的三个可选选项:pgliteWasmModule?: WebAssembly.ModuleinitdbWasmModule?: WebAssembly.ModulefsBundle?: Blob | File

注意类型要匹配:

  • pgliteWasmModuleinitdbWasmModule需要是WebAssembly.Module,所以用WebAssembly.compileStreaming(fetch(...))来编译,它返回的正是这个类型。
  • fsBundle需要是Blob | File,所以用fetch('/pglite.data').then((r) => r.blob())得到一个Blob

/pglite.wasm/initdb.wasm/pglite.data这三个路径对应你在第一步里放到站点根目录的文件。如果你的部署里静态资源挂在别的子路径下,把 fetch 里的路径改成对应的实际地址即可,但要保证路径指向的就是刚才复制的那三个文件。

验证:确认实例能正常查询

创建成功后db就是一个可用的 PGlite 实例。用项目 README 里的标准查询来验证它确实跑起来了:

const result = await db.query("select 'Hello world' as message;") // 文档示例:{ rows: [ { message: "Hello world" } ] }

如果这条查询按 README 示例返回了rows,说明 WASM 模块和数据文件都正确加载了,资源解析问题已经解决。

排查:fsBundle 大小不匹配时的报错

如果你手动复制了pglite.data,但要留意一个校验点。源码里会检查fsBundle的实际字节数是否等于期望的包大小,不一致时抛出Invalid FS bundle size: ${fsBundleBuffer.byteLength} !== ${remotePackageSize}(见 pglite.ts#L377-L387)。如果你看到这条报错,通常意味着你复制的pglite.data和当前@electric-sql/pglite版本不配套——重新确认你复制的三个文件都来自当前安装版本的node_modules/@electric-sql/pglite/dist/,而不是旧版本或别处的残留文件。

可选:改用 esbuild 插件自动处理

如果你不想手动搬运和传入这三个文件,文档给了另一条路径:使用 esbuild 插件(如@chialab/esbuild-plugin-meta-url)来自动处理new URL()导入。这样可以让 esbuild 自己解析出 URL 指向的资源,省去手动复制和手动传参的步骤。是否采用取决于你的项目是否方便引入额外插件;上面手动提供三项的方式则是文档给出的、不依赖任何插件的通用解法。

两种方案的边界:手动方式不引入任何新依赖,但需要你保证静态服务器能正确提供这三个文件,并在代码里明确传参;插件方式改动集中在 esbuild 配置里,但需要引入并正确配置该插件。选哪条,以你的构建约束为准。

【免费下载链接】pgliteEmbeddable Postgres with real-time, reactive bindings.项目地址: https://gitcode.com/GitHub_Trending/pg/pglite

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询