nodenv-package-json-engine
nodenv-package-json-engine copied to clipboard
Auto-installation
Hey there :wave:
Would you consider an auto-installation feature in your plugin?
Right now, I'm relying on multiple project/hooks/configurations on my setup to achieve that (e.g.: watch the package.json file, auto-install and enable the missing Node.js versions). It would be great to have the whole thing in one place.
I'm willing to create a PR by the way, but as I never contributed to nodenv, I would appreciate some guidance on the API design.
I have some thoughts, but first I'd like to dig into why you have file-watching on package.json. Are you iterating on changes to the #engines field? For what purpose? I would generally expect that property to be static and very rarely change. (like, exceptionally rarely)
But to the "automatic install":
First I'll point out that, if you're in a directory that has .node-version, then nodenv install (without any further arguments) will attempt to install the version specified in that file.
Which would lead one to assume that in a directory without a .node-version file (but with this plugin installed and a package.json#engines property), nodenv install would attempt to install the version specified in the engines field. It does not (presently). That would require some work in node-build's install plugin in order for it to trigger the version lookup hook that this plugin uses to resolve by package.json.
But there's a slightly bigger concern; if we did update the node-build install plugin to do so, (or we used some other means to trigger an automatic install) we'd quickly run into the issue that: package.json#engines is meant to specify a semver version spec (ie, range) of versions. Not a singular version.
How would you expect a hypothetical nodenv install ">=0.10" to behave? Should it install the very latest version that meets that requirement? The latest stable? The latest pre-release? The latest LTS release? Or the latest Current release? Or the oldest one that satisfies?
Most projects that have an engines field throw in <= whatever we're _currently using_ and then never touch it again. Which means if you jump into an old project, it might say <= 0.10, but it's very unlikely to work with anything after 6.0. So any assumption of "latest that satisfies" is probably not desirable.
On the flip side, if I jump into a super old project like that, I also wouldn't want my machine to automatically try to install an ancient version like 0.10, which probably doesn't even compile on modern hardware (least of all M1).
Now with all that complication out of the way, I do think it would be proper of node-build's install plugin to leverage the same hooks that nodenv version do for version resolution. That would make the nodenv install command congruent with nodenv version. Regarding all the questions above, my vote for now would be to simply punt completely if a non-exact version were define in package.json. That would allow the simple case to work as expected:
- precise version specified in package.json#engines; but not installed
nodenv installwould install the exact requested version
TBH, that is probably the extent of what we'd want nodenv to handle. If that sounds reasonable, I'll move this thread over to the node-build repo since it would be node-build's install plugin that needs to change.
I have some thoughts, but first I'd like to dig into why you have file-watching on package.json. Are you iterating on changes to the #engines field? For what purpose? I would generally expect that property to be static and very rarely change. (like, exceptionally rarely)
On specific projects, we only rely on the engines field, which is not used as a range, just like the dependencies. We want to have full control and predictability over the Node.js version.
And we didn't create the .node-version file because it's not supported by dependabot unfortunately.
But to the "automatic install":
First I'll point out that, if you're in a directory that has
.node-version, thennodenv install(without any further arguments) will attempt to install the version specified in that file.Which would lead one to assume that in a directory without a .node-version file (but with this plugin installed and a package.json#engines property),
nodenv installwould attempt to install the version specified in the engines field. It does not (presently). That would require some work in node-build'sinstallplugin in order for it to trigger the version lookup hook that this plugin uses to resolve by package.json.
Exactly, that was my first lead towards a "better" DX actually (better in our specific context).
But there's a slightly bigger concern; if we did update the node-build install plugin to do so, (or we used some other means to trigger an automatic install) we'd quickly run into the issue that: package.json#engines is meant to specify a semver version spec (ie, range) of versions. Not a singular version.
How would you expect a hypothetical
nodenv install ">=0.10"to behave? Should it install the very latest version that meets that requirement? The latest stable? The latest pre-release? The latest LTS release? Or the latest Current release? Or the oldest one that satisfies?
As a reference, NVM installs the latest version that fits the range.
Most projects that have an engines field throw in
<= whatever we're _currently using_and then never touch it again. Which means if you jump into an old project, it might say <= 0.10, but it's very unlikely to work with anything after 6.0. So any assumption of "latest that satisfies" is probably not desirable.
And yet, that's what's configured so... But I clearly hear you indeed.
On the flip side, if I jump into a super old project like that, I also wouldn't want my machine to automatically try to install an ancient version like 0.10, which probably doesn't even compile on modern hardware (least of all M1).
Yep :/
Now with all that complication out of the way, I do think it would be proper of
node-build's install plugin to leverage the same hooks thatnodenv versiondo for version resolution. That would make thenodenv installcommand congruent withnodenv version. Regarding all the questions above, my vote for now would be to simply punt completely if a non-exact version were define in package.json. That would allow the simple case to work as expected:1. precise version specified in package.json#engines; but not installed 2. `nodenv install` would install the exact requested versionTBH, that is probably the extent of what we'd want nodenv to handle. If that sounds reasonable, I'll move this thread over to the node-build repo since it would be node-build's
installplugin that needs to change.
It would be great to see that happening, to be honest. Thank you very much for your effort on that topic, it's really appreciated :heart: