Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to prebuildify? #9

Closed
markandrus opened this issue Oct 12, 2024 · 2 comments
Closed

Migrate to prebuildify? #9

markandrus opened this issue Oct 12, 2024 · 2 comments

Comments

@markandrus
Copy link

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…
  1. Change the ci:prebuild script in package.json:

    "ci:prebuild": "prebuildify --runtime napi --target 16.0.0 --strip --verbose",
    
  2. Remove the install script from package.json. Alternatively, it could be kept and set to node-gyp-build, per the prebuildify docs; however, that would require publishing the binding.gyp and other files that are not currently published in order for it to work. In my case, the machine that installs @pg-nano/pg-parser isn't going to have the tools to build it from source anyway, so I skip this step.

  3. Update dependencies in package.json. bindings, prebuild, and prebuild-install can be removed. node-gyp-build can be added as a dependency, and prebuildify can be added as a dev dependency.

  4. Update files in package.json to include the prebuilds/ directory.

  5. Change src/lib/binding.ts. The README.md for prebuildify suggests using node-gyp-build to 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
@markandrus
Copy link
Author

I implemented this on a public fork. You can see the commit here and try it like this:

npm install @markandrus/pg-parser@16.1.4-markandrus-1

@aleclarson
Copy link

I was aware of prebuildify when I decided on prebuild-install. Not a fan of the wasted disk space :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants