-
Notifications
You must be signed in to change notification settings - Fork 5
Description
The README.md for prebuild-install suggest migrating to prebuildify where, instead of publishing native binaries to the GitHub release, they are instead added to the prebuilds/ directory and published inside the package itself.
I have done this on my private fork, because it was easier to get working than figuring out how to access a private repo's GitHub releases. Benefits include (1) less dependence on GitHub releases, (2) potentially faster install times, and (3) no need for install scripts. However, it would mean slightly larger NPM packages and a different release process.
Steps I took…
-
Change the
ci:prebuildscript inpackage.json:"ci:prebuild": "prebuildify --runtime napi --target 16.0.0 --strip --verbose", -
Remove the
installscript frompackage.json. Alternatively, it could be kept and set tonode-gyp-build, per theprebuildifydocs; however, that would require publishing thebinding.gypand other files that are not currently published in order for it to work. In my case, the machine that installs@pg-nano/pg-parserisn't going to have the tools to build it from source anyway, so I skip this step. -
Update dependencies in
package.json.bindings,prebuild, andprebuild-installcan be removed.node-gyp-buildcan be added as a dependency, andprebuildifycan be added as a dev dependency. -
Update
filesinpackage.jsonto include theprebuilds/directory. -
Change
src/lib/binding.ts. TheREADME.mdforprebuildifysuggests usingnode-gyp-buildto load the addon. Depending on whether feat: dual-publish ESM and CJS #8 is accepted, the "isomorphic__dirname" trick can be used to get the correct path in both CJS and ESM:import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import type { Node } from './ast' const _dirname = typeof __dirname !== 'undefined' ? __dirname : dirname(fileURLToPath(import.meta.url)) const loadAddon = () => require('node-gyp-build')(join(_dirname, '..'))
Additionally, when building on macOS, I use the following script and Dockerfiles to build for Linux before publishing:
set -e
rm -rf prebuilds
docker rm pg-parser-builder-amd64
docker rm pg-parser-builder-arm64
cat >amd64.Dockerfile <<EOF
FROM --platform=linux/amd64 node:lts-bullseye
WORKDIR /app
COPY . .
RUN corepack enable pnpm
RUN cd libpg_query && make clean && cd ..
RUN pnpm build
RUN npx prebuildify --runtime napi --target 16.0.0 --strip --verbose
RUN node -e "import('./lib/index.js').then(({ parseIntervalSync }) => console.log(parseIntervalSync('1 year')))"
EOF
cat >arm64.Dockerfile <<EOF
FROM --platform=linux/arm64 node:lts-bullseye
WORKDIR /app
COPY . .
RUN corepack enable pnpm
RUN cd libpg_query && make clean && cd ..
RUN pnpm build
RUN npx prebuildify --runtime napi --target 16.0.0 --strip --verbose
EOF
docker build -t pg-parser-builder-amd64 -f amd64.Dockerfile .
docker build -t pg-parser-builder-arm64 -f arm64.Dockerfile .
docker create --name pg-parser-builder-amd64 pg-parser-builder-amd64
docker create --name pg-parser-builder-arm64 pg-parser-builder-arm64
docker cp pg-parser-builder-amd64:/app/prebuilds .
docker cp pg-parser-builder-arm64:/app/prebuilds .
pnpm run ci:prebuild