在 Expo Web 中使用 PowerSync
Expo 使用 Metro。Bundler,仅支持 CommonJS Module,而 PowerSync (及其依赖的 wa-sqlite 项目)仅支持 ESM,所以需要一些 hack 的手段来 Expo Web 环境下支持 PowerSync
准备 Web Workers Scripts
核心的点在于不要使用 npm 中自带的 Web Worker 脚本(因为其所利用的 import.meta.url
在 CommonJS Module 中不被支持),所以我们需要提取 Web Worker Scripts 然后让他在浏览器中利用 URL 加载。
Web Worker Scripts 的提取我写了个脚本获取,请参考 powersync-web-workers 仓库。下载 dist 中目录的内容,放置在你项目中的 public/lib/powersync/worker
目录下,效果如下
如果你所使用的 @powersync/web 版本不被仓库直接支持(可参考 tags),需要自行修改 package.json 文件中 @powersync/web 的版本并 build(具体可参考该仓库 README)
> tree public/lib/powersync/worker
public/lib/powersync/worker
├── db
│ ├── SharedWASQLiteDB.worker.js
│ ├── WASQLiteDB.worker.js
│ ├── wa-sqlite-async.wasm
│ └── wa-sqlite.wasm
└── sync
└── SharedSyncImplementation.worker.js
3 directories, 5 files
Patch @powersync/web
因为 @powersync/web 不支持使用外部 URL 加载 Web Worker Script,所以需要进行一些 patch
以下 patch 以 pnpm 为例演示,你也可以自行使用 patch-package 来实现相同的效果
如果你使用的版本直接被仓库支持(可参考 tags),则只需复制 patch 文件(@powersync__web@xxx.patch
)然后配置 pnpm patch 即可
如果你使用的版本不被仓库直接支持,则需要手动进行下面的操作:
下载最新的 patch 文件,假设存放于
/tmp/@powersync__web@xxx.patch
在项目目录下执行
pnpm patch @powersync/web
打开第二步所输出的目录
在目录中执行
patch < /tmp/@powersync__web@xxx.patch
回到项目目录下执行,执行第二步所打印的 pnpm patch-commit 命令
提示:如果该项目「年久失修」,第四步的 patch 可能执行失败,你可能需要自行研究 patch 文件来替换脚本 URL