https://blog.orhun.dev/packaging-rust-for-npm/
Opened this issue · 12 comments
Orhun's Blog
Hi, great blog post. What prevents you from publishing all binaries as part of a GitHub release and download the exact version in "post-install" hook? (example) In that way, you don't need to publish a package per ARCH and the user doesn't need to download all variants on every install. Depending on the package it could result in multiple hundred megabytes of waste. Your approach is a good candidate if you can't use npm hooks.
Hey @StarpTech! That totally makes sense, I wish I knew that before! It seems like a simpler and more straightforward approach. Thanks for sharing!
Hi, great post.
Why would you prefer to prebuild all binaries, instead of just building them during installation?
I was curious about the tradeoff between "package per arch" as you describe it and @StarpTech's "post-install" approach. They both have their benefits, but I think on balance I prefer package per arch.
According to my quick and possibly fallible test, it doesn't download the packages for other platform variants either. At least my node_modules
ends up looking like
node_modules
├── git-cliff
│ ├── lib
│ ├── package.json
│ ├── README.md
│ ├── src
│ └── tsconfig.json
└── git-cliff-linux-x64
├── bin
├── package.json
└── README.md
as expected and according to iftop
the install (with caches cleared previously) only downloaded 3.2 MB, which is only slightly more than the compressed size of the package for my platform. So no downsides there.
While post-install does look a bit simpler, I think it's just trading the complexity of publishing several packages with that of creating a GitHub release and uploading the artifacts to it. If you do that from a GitHub action, it feels about the same to me.
Finally the neat thing about package per arch is that absolutely everything you need for installation is on NPM, there's no second system like GitHub's CDN involved. Plus the installation is entirely declarative and does not depend on my possibly buggy install code that could leave the system in a bad state if I screwed it up 🙂
In any case, thanks for the detailed article and example, and of course publishing git cliff
on NPM. Now that it's so easy to include, I'll definitely try it in one of my projects.
Hi, great post. Why would you prefer to prebuild all binaries, instead of just building them during installation?
Thank you! Building binaries during installation would take too much time especially considering the build times of Rust projects. This approach is simpler due to the fact that you only build once and distribute the binaries inside packages. There might be a question about security, though.
While post-install does look a bit simpler, I think it's just trading the complexity of publishing several packages with that of creating a GitHub release and uploading the artifacts to it. If you do that from a GitHub action, it feels about the same to me.
Finally the neat thing about package per arch is that absolutely everything you need for installation is on NPM, there's no second system like GitHub's CDN involved. Plus the installation is entirely declarative and does not depend on my possibly buggy
install code that could leave the system in a bad state if I screwed it up slightly_smiling_face
That's an excellent summary. I was worried if post-install approach would be better but your points made absolute sense to me. Thanks!
In any case, thanks for the detailed article and example, and of course publishing
git cliff
on NPM. Now that it's so easy to include, I'll definitely try it in one of my projects.
So good to hear! ⛰
@nihohit, I believe not every Node.js developer or CI service (at least with a Node.js configuration) have the right tools to build the binary. Having to build things from scratch every time you install them seems like a strange idea to a JS dev like me xD. But it may just be a preference. At the end of the day when you run yarn add -D git-cliff
, it should install the final product and you should be able to use it out of the box.
Could you also easily publish it for eg. python?
Another downside of packaging all binaries in the npm package is the docker image size. It gets hard to clean this up across different package managers with different hoisting strategies. Image size is crucial to deployment and startup time.
Could you also easily publish it for eg. python?
We're currently working on a PR for that :3
It is not the exact approach as NPM, but definitely simpler.
can anyone guide me to integrating an another npm package to it
Thanks for this post it was very helpful :)
For those who kept having their index.js
getting added to src
on the build step, be sure to give compilerOptions.outDir
in your tsconfig.json
the "./lib"
value.