orhun/personal-blog

https://blog.orhun.dev/packaging-rust-for-npm/

Opened this issue · 12 comments

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.

orhun commented

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.

orhun commented

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.

orhun commented

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! ⛰

atlj commented

@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.

orhun commented

Could you also easily publish it for eg. python?

We're currently working on a PR for that :3

orhun/git-cliff#158

It is not the exact approach as NPM, but definitely simpler.

Gmin2 commented

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.