nvm
nvm copied to clipboard
Honor .node-version file
Forgive me if this has been discussed before, but I didn't find anything beyond https://github.com/creationix/nvm/issues/110#issuecomment-40525629.
It would be really nice to see the various Node version managing tools coalesce around a common "version config file", analogous to Ruby's .ruby-version
for RVM and rbenv - .node-version
. This would basically just be an alias for .nvmrc
, since that functionality's already been added. Since n
already supports .node-version
, this would make it so that regardless of the Node version manager used, there could be some degree of guarantee that the correct version will be used.
When did n
add support for node-version
?
Which would win if you had both files present?
What about the different version formats that nvm
supports - ie, iojs
, stable
, node
, or 0.10
, etc - and how do other version managers interact with those? What special formats do they offer that nvm
might be forced to interact with?
When did n add support for node-version?
Ah sorry, my mistake, it wasn't n
- it's avn
and nodenv
. I actually asked the Stack Overflow question about this awhile back.
Which would win if you had both files present?
I think I'd expect .nvmrc
to win if both files were present, but I don't really have strong feelings about this.
What about the different version formats that nvm supports - ie, iojs, stable, node, or 0.10, etc - and how do other version managers interact with those? What special formats do they offer that nvm might be forced to interact with?
That's a good question - I'll have to research this a bit.
I'd never heard of nodenv
, but avn
alone isn't enough for it to be a "common" version file. Do note my answer on that question which I think is a bit better than the accepted one http://stackoverflow.com/a/29545541 :-)
+1
Rapid, per-project .ruby-version switching with rvm is too useful not to have this for Node.js!
:+1:
I think the idea here is that even though .nvmrc
already provides this functionality, having a more generic cross-implementation .node-version
file would be beneficial.
As @ljharb pointed out though, interoperability here would require more than just a common filename. iojs
, stable
, node
are also valid version numbers for nvm, but not necessarily for other implementations. I'm honestly not sure how that should be handled. Maybe some discussion with the maintainers of other node versioning-type projects is in order...
If all of nave
, n
, avn
, and whoever else all wants to cleave to nvm
s "version-ish" format, or, at least is prepared to accept or reject it gracefully (for example, supporting a version number but not a generic tag), that's great. Note that soon I'll have release candidate support for io.js
and node
, and these will have a different prefix as well, and who knows what the future will bring?
Just for .nvmrc files - https://github.com/lalitkapoor/nvm-auto-switch - I appreciate any feedback. Thanks!
Please use github reactions on the original post rather than posting "+1". Fair warning, I'll clean up existing and future comments that simply say that.
If all of nave, n, avn, and whoever else all wants to cleave to nvms "version-ish" format, or, at least is prepared to accept or reject it gracefully (for example, supporting a version number but not a generic tag), that's great.
That's not a problem, at all...
nvm
could use .node-version
as an alternative, but still giving preference to .nvmrc
.
Project owners could decide to use a wider syntax on .node-version
(just the version number, which, I think, it's most of cases) to allow use of any version manager OR use a specialized syntax and prefix on .nvmrc
.
I don't even think nvm
should care about which file is in use, but just parse .nvmrc
or .node-version
(in this order).
I'm not sure if I even like this idea, but a generic approach to "supporting" node-version directly might be to support a syntax in nvmrc that allows people to read the version string from any other file.
// .nvmrc
file:.node-version
// .node-version
6.3.1
This approach does have some pleasant side effects:
- No chasing additional version "standards" once the precedent has been set by supporting .node-version
- No questions of precedence
- No need to hardcode any subtle differences in support between the two standards since you're essentially making the assumption that the other file is compatible with nvm rather than the other way around.
That's not a half-bad idea. However, file:.node-version
is a valid alias name, so it'd probably have to be something with a slash in it.
I'll think about that one more.
.node-version is a much more sane name than .nvmrc
furthermore, I don't see why it shouldn't support both
@TylerBre please don't use ableist terms like "sane".
node-version
would work if it was a universal version identifier. However, nvm
supports io.js, and aliases, neither of which are necessarily "node" or "universal".
Even though nvm support io.js, .node-version
would still be relevant. And to be fair, nvm stands for "node version manager", and io.js isn't node, it's node compatible. That being said, I think it should be possible to honour .node-version
for node versions, and maybe then also support .iojs-version
, if that's still relevant for someone.
io.js is node, versions 1-3, after the fact.
You're also missing the most important part, which is "aliases".
The purpose of .node-version
is that you want a static, consistent version. Specifying an alias would defy that purpose.
I agree - which would mean that nvm
respecting node-version
would have to be limited to static versions only.
What do avn
and nodenv
support in node-version
files? If it's just "a static version, with or without a leading v
" then the possibility still remains open that nvm
could support that too.
nodenv differentiates between node and iojs with definitions like 0.10.36
and iojs-1.0.0
(as seen in their README). And it requires that exact version to be installed.
Installing of that version can be done by running nodenv install
(with the node-build
plugin added).
Does nodenv
work if you do have a v
prefix? (does rvm
support the v
in .ruby-version
?)
My assumption was it wouldn't work with the v
prefix, but it does:
$ cat .node-version
v5.12.0
$ nodenv version
5.12.0 (set by /Users/koenpunt/.../.node-version)
rvm I don't know, but rbenv does, as is about the same as nodenv (nodenv is a port of rbenv)
That's encouraging - it means we could support v1.2.3
or 1.2.3
. I'm hesitant to include the "iojs-" prefix, though, since there's no overlap with node - unless every other node version management tool supported it too.
Either way I've filed https://github.com/nodejs/version-management/issues/13, and I think this issue should be blocked on that.
I just swung by to leave an issue and see if there was any interest in this, but looks like there is!
RVM and rbenv both have their own files and formats but both agree on .ruby-version
, and it would be lovely if nvm and nodenv could agree on a common file too, even if nothing changes by default.
Here's how RVM load the file:
.rvmrc - shell script allowing full customization of the environment, .versions.conf - key=value configuration file .ruby-version - single line ruby-version only Gemfile - comment: #ruby=1.9.3 and directive: ruby "1.9.3"
So, we could very easily add another function to check for .node-version
if there is no .nvmrc
, agreed?
Here you go! https://github.com/creationix/nvm/pull/1625
I'd never heard of nodenv, but avn alone isn't enough for it to be a "common" version file.
fnm also supports .node-version
https://github.com/fisherman/fnm/blob/503b07d3b419908409373699c227c4baf32b4b7b/functions/__fnm_read_fnmrc.fish#L4
+1 would love this, colleagues and I use different version managers - the support will help keep us in sync.
.node-version
is also supported by the nodejs plugin for ASDF, a universal version manager (nodejs, ruby, etc etc)
nvs also supports .node-version
it's kinda annoying needing to have 2 files because different people have different preferences.
This repo offers a pretty comprehensive growing list of the version managers that honor .node-version
:
https://github.com/shadowspawn/node-version-usage
Perhaps you could honor both? 🤷🏻♂️ Detect .nvmrc
first and support more advanced features there but, if that isn't present, detect .node-version
and only support its subset of features? 🤔
I know supporting multiple can be a slippery slope but it feels like a reasonable maintenance burden at the moment (to me, as an admitted non-maintainer 😅). ❤️
Yes, the growing list means it's almost certainly never going to be possible for this specific file to become a standard.
zOMG 2021 and this shit still doesn't support anything but .nvmrc
‽ 🤯
@sshaw that's a hostile comment, and yes, the date has no bearing on whether there's support for a nonstandard file. we don't support anything right now but our own file, since there's no standard, and that's what every other tool should be doing too.
@ljharb ... the date has no bearing on whether there's support for a nonstandard file. we don't support anything right now but our own file, since there's no standard, and that's what every other tool should be doing too.
A lack of a standard shouldn't inhibit interoperability especially when other tools i.e., your competitors, have implemented what I think is fair to call "working support" for them and, in some cases on top of their own file.
What is the (edge) case that makes the entire case for supporting .node-version
unreliable or, a non-starter due to "lack of standard"?
Interoperability is only POSSIBLE with a standard. There isn't any such interoperable standard defined for that file.
Some other maintainers may be willing to offer "working support", but I'm unwilling to ship anything that doesn't have full, eternal support.
Interoperability is only POSSIBLE with a standard.
I've been using asdf and at times nodenv with .nvmrc
s for several years. Looks to be pretty operable to me! Maybe I was dreaming? Was curious about the faulty cases. Aliases you mention but the others: who knows!
I'm very glad your experience has been positive. I do hope you understand that the sum of "anecdotes" is not "data", though, and that what's far more likely is that those who have encountered problems have simply not used that filename to avoid them.
Aliases (user-defined ones; version-manager-defined ones, like nvm's iojs
or node
; node-defined ones like LTS names or release channel names), fuzzy specifiers (like 14
or 14.1
instead of the fully-qualified version number), to name a few.
I added this to my zsh profile to autoload a node version from either .nvmrc or .node-version (with fallback to default if neither found):
# Set node version
function change_node_version() {
local nvmrc_path="$(pwd)/.nvmrc"
local node_version_path="$(pwd)/.node-version"
if [ -f $nvmrc_path ]; then
echo ".nvmrc file exists."
version="$(cat "$nvmrc_path")"
nvm use $version
elif [ -f $node_version_path ]; then
echo ".node-version file exists."
version="$(cat "$node_version_path")"
nvm use $version
else
echo "Neither .nvmrc nor .node-version files exist."
nvm use default
fi
}
chpwd_functions+=(change_node_version)
If you are interested in augmenting the existing function mentioned in the README, I highlighted the lines that you need to copy from @alex-latham's solution:
load-nvmrc() {
local node_version="$(nvm version)"
local nvmrc_path="$(nvm_find_nvmrc)"
+ local node_version_path="$(pwd)/.node-version"
if [ -n "$nvmrc_path" ]; then
local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
if [ "$nvmrc_node_version" = "N/A" ]; then
nvm install
elif [ "$nvmrc_node_version" != "$node_version" ]; then
nvm use
fi
+ elif [ -f $node_version_path ]; then
+ version="$(cat "$node_version_path")"
+ nvm use $version
elif [ "$node_version" != "$(nvm version default)" ]; then
echo "Reverting to nvm default version"
nvm use default
fi
}
I find nodenv[-install] to be highly reliable these days. Wonder if that supports querying desired node version ranges from package.json.
On Tue, Mar 22, 2022, 2:52 PM Carlos Molina A @.***> wrote:
If you are interested in augmenting the existing function mentioned in the README https://github.com/nvm-sh/nvm#zsh, I marked the lines that you need to copy from @alex-latham https://github.com/alex-latham's solution:
load-nvmrc() { local node_version="$(nvm version)" local nvmrc_path="$(nvm_find_nvmrc)"+ local node_version_path="$(pwd)/.node-version"
if [ -n "$nvmrc_path" ]; then local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")") if [ "$nvmrc_node_version" = "N/A" ]; then nvm install elif [ "$nvmrc_node_version" != "$node_version" ]; then nvm use fi+ elif [ -f $node_version_path ]; then+ version="$(cat "$node_version_path")"+ nvm use $version elif [ "$node_version" != "$(nvm version default)" ]; then echo "Reverting to nvm default version" nvm use default fi
}
— Reply to this email directly, view it on GitHub https://github.com/nvm-sh/nvm/issues/794#issuecomment-1075575965, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAABJRBPHXO5HNZPNAF7PD3VBIQIDANCNFSM4BMT6JZA . You are receiving this because you commented.Message ID: @.***>
@ljharb
Is there any chance at all you would be willing to change your mind here? There is real developer pain caused by nvm's refusal to interop. This schism creates fragmentation pain felt by end users. The problem gets exacerbated further for non-development folks like designers and PMs who may want to try running apps locally and get tripped up when setup docs just say to install any node version manager of your choice. As you'd expect, nvm is the top search result for "node version manager".
I'd argue that .node-version
is already a de-facto standard (albeit, with gaps in specification). There is value in adherence to conventions. Markdown had no formal spec and was loaded with ambiguous edge cases, but it's become almost universally accepted. Sure, there are localized flavors of it now, but the commonalities of Markdown still deliver value. Even JSON didn't really have a formal standard till 2013, long after it already had wide usage.
I totally understand your perspective of wanting to only build on solid foundations. My perspective here is that more harm is done by not supporting .node-version
. The conventions around .node-version
are to support a subset of what .nvmrc
supports. Just treating .node-version
the same as .nvmrc
would address the interop concerns.
If you're dead set against making this default behavior, could you let this work off an env variable?
@bilalq there's no "refusal" to interop - no interop exists, because there's been no group consensus reached about the specification for the .node-version
file.
A defacto standard requires a predominant subset of semantics, which nobody's illustrated exist. Is the "v" prefix required, optional, or forbidden? Is a semver version triple required, or can a major.minor
or major
be specified? In the latter two cases, is a trailing dot required, optional, or forbidden?
The most POSSIBLE harm is done by implementing a nonstandardized potential standard - and this includes every existing tool that supports this wildly underspecified filename.
The predominant subset of semantics, supported by all utilities I have examined, is:
- no v prefix
- semver triple
- unix line ending
https://github.com/shadowspawn/node-version-usage
I'd recommend following Robustness Principle, and implementing what gives people value, recognising commonly used patterns that may become standardised in the future.
Even if there was a standard, according to the robustness principle it would be a good practice if nvm
accepted more formats beyond standardised. There's no reason for gatekeeping just because there's no agreed version - unsurprisingly other tools & IDEs found their way to help people, by just implementing what seemed a good judgement of most used values.