build(ci): wire better-sqlite3 native binding into release artifacts
Followup to 0b6541c. That commit added `better-sqlite3` as a
workspace dependency and marked it as a vite external — meaning
the bundled `dist/index.mjs` does `require('better-sqlite3')` at
runtime instead of inlining its JS wrapper. Without the binding
+ wrapper present in the production archive, every shipped
SnowLuma would crash on first SQLite op.
The fix is in three small pieces:
1. `packages/runtime/package.json` — declare `better-sqlite3` as a
runtime dep. `vite-plugin-cp` copies this manifest into
`dist/package.json` during build (see `runtimeDistFiles` in
`packages/core/vite.config.ts`), so the release workflow's
existing `npm install --omit=dev` step inside `dist/` picks it
up and compiles the native binding for the matrix target via
prebuild-install (with node-gyp fallback). This is the same
mechanism release.yml has used since v1.x — it was just empty
until now because the previous vite config bundled everything.
2. `.github/workflows/dev-build.yml` — mirror the
`Bundle runtime dependencies` step from release.yml. Dev-build
was packaging `dist/` straight after vite, which would have
shipped a broken artifact (no `dist/node_modules/`). Added the
`npm install --omit=dev` step before the tar/zip packaging
steps so dev-build archives carry the binding too.
3. `package.json` root — add `dist:install` script (just
`cd dist && npm install --omit=dev`) so local prod-mimic flows
work: `pnpm build && pnpm dist:install && pnpm dev:mode`. Not
chained into `pnpm build` itself to keep the watch-cycle fast
for users who only need the vite build output; the install
step adds ~17s.
Note on dev mode: `pnpm dev` continues to work unchanged — it
runs via tsx against workspace `node_modules/`, which already has
`better-sqlite3` compiled (from the workspace-level pnpm install).
Only the dist/-based prod-mimic path needed the explicit install.
Verification
------------
- `pnpm build` (with stubbed native binary): clean, dist/ has the
updated `dist/package.json` with the dependency declared
- `pnpm dist:install`: installs 38 packages, compiles
`dist/node_modules/better-sqlite3/build/Release/better_sqlite3.node`
- Smoke-test from `dist/`: `node -e "import('better-sqlite3')..."`
prints `OK: [ { id: 42 } ]`, confirming the binding loads + a
basic INSERT/SELECT roundtrip works.
CI matrix coverage: win-x64, linux-x64, linux-arm64 (release.yml +
dev-build.yml share the same matrix). Each builds its own native
binding during the install step — prebuild-install hits
better-sqlite3's prebuilt-binary registry for these three targets
(no source compile needed in the common case, falls back to
node-gyp if a prebuilt isn't available).
This commit is contained in:
@@ -110,6 +110,17 @@ jobs:
|
||||
SNOWLUMA_TARGET: ${{ matrix.target }}
|
||||
run: pnpm run build:all
|
||||
|
||||
# Materialize `dist/node_modules/` for runtime-only externals
|
||||
# listed in `packages/runtime/package.json::dependencies`
|
||||
# (currently: better-sqlite3 — native binding can't be inlined
|
||||
# by vite). Mirrors the same step in `release.yml`. Runs npm
|
||||
# (not pnpm) deliberately so the install produces a flat
|
||||
# `node_modules/` tree with no symlinks, which is what the
|
||||
# bundled `index.mjs::require('better-sqlite3')` expects.
|
||||
- name: Bundle runtime dependencies
|
||||
working-directory: dist
|
||||
run: npm install --omit=dev
|
||||
|
||||
# Naming convention:
|
||||
# SnowLuma-dev-<arch>.zip|tar.gz – zero-install (node bundled)
|
||||
# SnowLuma-dev-<arch>-lite.zip|tar.gz – user provides Node >= 22
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"build:webui": "pnpm --filter webui build",
|
||||
"build:all": "pnpm --filter @snowluma/core build:all && pnpm --filter @snowluma/sdk build && pnpm --filter webui build",
|
||||
"dev": "pnpm --filter @snowluma/core dev",
|
||||
"dist:install": "cd dist && npm install --omit=dev",
|
||||
"dev:mode": "cd dist && cross-env SNOWLUMA_DEV_MODE=1 SNOWLUMA_DEV_WEBUI=1 node index.mjs",
|
||||
"dev:web": "pnpm --filter webui dev",
|
||||
"test": "pnpm --filter @snowluma/core test",
|
||||
|
||||
@@ -4,5 +4,8 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "index.mjs",
|
||||
"description": "SnowLuma runtime distribution manifest: ships into dist/ (launcher.bat, package.json, native/*.dll, native/*.node). Native libraries are loaded via process.dlopen()."
|
||||
"description": "SnowLuma runtime distribution manifest: ships into dist/ (launcher.bat, package.json, native/*.dll, native/*.node). vite-plugin-cp copies this package.json into dist/, then the release workflow runs `npm install --omit=dev` inside dist/ to materialize the production node_modules. Dependencies listed here are the runtime-only externals that vite did NOT bundle into index.mjs (currently: better-sqlite3 — native binding, can't be inlined).",
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^11.7.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user