postinstall creates a whole host of issues which it would be nice to not have to deal with.
I've seen a similar issues when distributing native node binaries and wonder whether some of the solutions I've seen in use there might be an improvement here.
Firstly, you publish an npm package per platform/arch combo (@sentry/cli-{platform}-{arch}) and include the cli binary in there.
- In
package.json set main as the path to the binary and then it can be found later by simply require.resolve('@sentry/cli-${process.platform}-${process.arch}')
- In
package.json correctly define os and cpu properties which ensures that they will only install on the correct platform/arch
- You can even set
bin in these packages if you want them to be directly accessible.
Then in @sentry/cli you list all the above as optionalDependencies. After this, when installing @sentry/cli, npm/yarn will attempt to install all the optional dependencies and only succeed on those where the os and cpu match.
Bonus: If your JavaScript code used to find the binary uses complicated enough dynamic paths construction, @vercel/nft gives up and wont include them.
This approach is already used by Parcel, Next.js and plenty of others.
Downsides?
- It is perhaps abusing
optionalDependencies but everyone appears to be on this train now so maybe it wont crash?
- Does npm/yarn have to download all the optional dependencies before checking the
os and cpu? 🤔