-
Notifications
You must be signed in to change notification settings - Fork 664
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
fix: nan and cpu-features should be really optional #1080
Conversation
A few points:
The whole point of these optional dependencies are to improve the end user's runtime performance out of the box. If their installations are not automatically attempted, users will not know (or possibly want) to do perform steps manually to get the performance benefits. The other thing is, it was either for node-gyp 8.0 or possibly npm 8.0 that verbose build errors for |
Also, at least npm already provides flags for users who for whatever reason take issue with seeing build errors during |
Thanks for the comments, here's few remarks
"doesn't support peerDependencies by default" -> that's actually doing the same as "optional" true. So no difference in intended behaviour, am i wrong ? PS: IMHO, node 10 is unsupported -> remove node 10 support in ci -> ssh2 v6 would make sense.
Not sure about this on npm.... But peerDeps are inherited dependencies somehow, i find them a bit everywhere nowadays. Maybe this https:/npm/rfcs/blob/main/implemented/0025-install-peer-deps.md#motivation makes it a bit clearer.
You mean more confusing than failing on build cause node-gyp is not there ? 😄 (and that for all packages that depends on ssh2 and that even if they actually not use those nan and cpu-features)
Again the real thing is that the install actually breaks, but thanks to the def of optionalDependencies, it's allowed to. But why do we need to fail ? error log, time (on ci this taking 15-20s on each run to try a build - i use testcontainer-node) Am I missing something ? Do we really need this ?
Yes possible, can't find an rfc for it but some things looks going in the same direction: https:/npm/rfcs/blob/main/implemented/0030-no-install-optional-peer-deps.md#prior-art.
I don't think this will gain wide adoption across package managers. By nature that would make a lock change depending on how you install ? Yarn 2+ dropped it seems: yarnpkg/berry#2412 (comment) I can't really argue about which format to give, and I'm just learning node... coming from different background. Cause I don't really know the project, an important question for me: Are cpu-features and/or nan supposed to be exposed externally by consuming packages ? Just to be sure
|
Ah I see, not really external but used as optimizations (assuming built succeed) https:/mscdex/ssh2/blob/master/lib/protocol/constants.js. Nice optims btw :) |
Yes, especially considering that npm clearly indicates in its logging that it's skipping the optional dependency when there's a build failure. Also, it wouldn't be because of missing node-gyp (that's bundled with npm), it would be a compiler error or other missing build infrastructure.
I only focus on npm because that's what's bundled with node and I don't think every package maintainer should be concerned with the idiosyncrasies of each package manager that exists out there.
FWIW the addon bundled in As far as The main driving force behind these optimizations was because of complaints users had made in the past about transfer speeds compared to other solutions. So in order to help alleviate those issues I implemented the aforementioned optimizations. Either way someone is evidently bound to complain and I'm a performance-oriented dev anyway, so I'm more inclined to stick with the way things currently are, especially given that like I said, npm/node-gyp is supposedly going to be hiding build errors for optional dependencies anyway. |
Another tidbit that's possibly worth throwing into this discussion is there is always the possibility of having pre-built versions of these optional dependencies, even though I'm personally not particularly fond of downloading/trusting binary blobs from npm, but if others would be happy with that then that might be worth exploring. I've yet to explore using Github Actions to generate such assets that could then be stored somewhere, perhaps a Github release as a download or something like that. |
Wow nice explanation ! Great I love this thread and yes in that case it is optionalDependencies. So here's another question... Would it make sense to find an alternative to cpu-features made in js/node ? I'll explain a bit the idea below: There's two conditions here, we would have to be able to
I think it's possible to make it work. PS: Need to know if node.arch would be sufficient. At least they give insights about what architecture node was compiled. There's some projects trying to detect that from runtime (better-arch and to some extend os-name, envinfo, systeminformation where we could find the necessary experience)
AFAIK the only way in node would be to compare to a list of cpu architecture. Let's say something in the lines of "i7, i9, amd have all AVE"... The fallback would be to go "don't support AVE". Just the same fallback when the cpu-features fail to build (which I imagine is happening a lot in real installs). Of course that wouldn't be 100% exact and this list might have to be updated... This is just ideas, of course... And I would be pleased to assist / explore / create P/R in this direction. Does it sound good to you ? Or is it something that you wouldn't like to consider ? |
Yes this is possible and quite exciting. My experience with binaries (esbuild, swc, sharp, sentry) is that they seems to need a lot of work... So many arch, linux style (alpine musl, arm...) and I've been struggling to make those work lately (on alpine mostly). PS: interesting too yarnpkg/berry#2751, but it's very early stage. |
Believe me, if it would be that easy, that's what I would've done in the first place. However you'll quickly find that if you start down that path, not only will you find yourself re-implementing fallbacks that Google's cpu_features already includes, but you'll also find that the only real (and cross platform) way to get reliable CPU info (especially CPU features) is at the C/C++ layer (even with that there are lots of edge cases and other considerations to be made that cpu_features already takes care of/smooths over). I'd much rather not have to maintain something of that scale, so that's why I chose to leverage cpu_features instead.
There are already modules that help with this sort of thing to some degree, such as node-pre-gyp. Github Actions already supports the big 3 OSes anyway (Linux, macOS, and Windows) and making various builds (32/64-bit, glibc/musl, etc.) on each platform where needed shouldn't be that difficult. There might even be existing tooling that takes care of all of most of this, I just haven't investigated it. |
Agree, but devils advocate saying --- "get reliable CPU" different than "get reliable node-gyp build" :) And I sense if we had usage stats, we would be surprised to see that most those optims aren't enabled at all. It's more about percentage of users that will effectively get the optims... Just saying, don't take any of this badly and I'm no expert (just discovering node for a few months)
Yep or the new kids on the block, like napi.rs which prisma use... They have a boilerplate too (I never tried, but I'd like to) and I guess it's possible to include things like https://crates.io/crates/cpufeatures... Not sure of the size though. But it's quite a work to do at first. I don't know if I would go there for now. |
I don't understand what you're trying to say here.
Switching to another compiled library would not change anything. At any rate, I feel like I've already laid out my position and believe there are no changes needed regarding the optional dependencies. I've given potential, existing solutions for npm users who have issues with seeing build errors for the optional dependencies that are not required to successfully use/install My suggestion at this point is to create issues on your favorite package managers' issue trackers about hiding optional dependency build errors if you're really concerned about seeing them. |
That maybe a js/node "non-perfect" solution would improve the actual detection for people not having cmake, and so on...
It took me time to understand that's a real optionnalDependency, was mistaken thinking it a was a peer. Now I know and it's perfectly fine. Sorry for misunderstandings if any. Happy day |
Changes
Moving "nan" and "cpu-features" to peerDependencies (optional). While "optionalDependencies" looks the way to do it, it's actually not really what's intended here (imho)
Will fix
Prevent errors (in ci or whenever cmake is not there) and make install faster when you actually don't need cpu-features or nan.
Related
(...)
Breaking changes ?
Moving to peerDependencies is the way to go (see context below, I can give other examples or threads).
If a dependent package used to rely on on 'nan' or 'cpu-features' without actually declare them in their deps, they'll have to do.
I have no idea how many packages actually rely on them, but as ssh2 is widely used (https://www.npmjs.com/package/ssh2), it might be safe to create a major version and add to the migration something like:
Context
"optionalDependencies" might not be what we're looking.
Quoting yarn doc:
Per definition "optional" will still install the packages, and often the build step is actually failing.... (in CI for example)
Why peerDependencies and meta ?
To achieve the expected goal, the idea is to use
peerDependencies
andpeerDependenciesMeta (with optional)
. It's supported in a consistent way by mainstream package managers: