Closed westoque closed 11 years ago
I'm not sure what it would do. NVM doesn't wrap the node executable, it just helps you manage multiple $PATH values.
Switch to the node version specified in .nvmrc? Why not use the package.json file?
But what will do the switching? Are you going to run nvm readconfig
or something every time you enter a new folder?
As far as I know the rvm checks on every cd
if the new folder contains a rvmrc and loads the appropriate config/ruby version. Maybe a ruby expert should say something about this :)
I just looked at how rvm implemented this. I am going to do the same approach.
I like this idea too, except that using the package.json
instead of a separate .npmrc
makes a a lot of sense to me as @booo says
There is already an engine version specified in the package.json file. There is zero need to add yet another dotfile to do this.
I'd love for nvm to do this automatically as well. But definitely not by adding yet another .whateverc
.
Hi guys,
For those interested, I spent some time this week end to write a proof of concept around the idea of parsing the package.json on a cd. Actually I use a ruby script to parse the json file and define what to do, since my bash-jutsu is quite limited. I didn't work much on the version operators either, so there's only a limited support (>=, <= and = are supported actually).
The fork can be found here: https://github.com/abe33/nvm/tree/feature_automatic_use_on_cd_with_package
Idea: regarding "auto-switching", would it be better if we just add an nvm command to pick the best version that's suited to the current folder's package.json?
something like
nvm select # auto-select a local version that best matches what's specified in package.json
I have used rvm before and honestly didn't like the cd-stealing approach. I already have a few commands that try to steal my cd
(autojump and rvm for example) and does some extra processings that I'm not aware of. IMO, running anything automatically on a cd
is a bad approach.
@chakrit : The last version includes the nvm select command as you requested and dissociate the change directory hook in a separate file. I also added the support for all the version range expressions (as documented here: https://npmjs.org/doc/json.html#dependencies, minus the git and http ones). I guess there's some edge cases I didn't tested yet, I'll update it as soon as I'll find them.
@abe33 nice! :) using your fork right now.
EDIT: ruby? ಠ__ಠ
@chakrit : Yes, as I said in my first comment, my skills with shell script aren't that good, and I had hard times to find out how to parse a json file with pure shell - re-writing a json parser wasn't really part of the plan ^^ - and writing the version matching algorithm was beyond my knowledge by far. If people have advice to how implement this in shell, I'll gladly try to port the ruby code :).
Related feature requst: http://cnodejs.org/topic/516a1f0e6d382773062dfd8a
I think use packge.json
for auto-switching is a nice solution.
I also think it would be nice to add an nvm command that can try to figure out the engine to use by parsing the package.json. I have a lot of projects with different node versions, so it’d be a time saver if I don’t have to go look into package.json myself to figure out which version I want to tell nvm to use.
But yeah, I’m not sure how easy it is to parse package.json in pure Bash.
@hydrozen sounds like you need a new tool. Let's not bloat nvm with complex features like this. Searching recursively through package.json files is non-trivial for a bash function. (parsing a single json file in bash is hard enough) Write a new tool that works in any version of node that outputs a string for the ideal node version to run, and then pass that string to nvm.
I'm going to close this issue. After thinking about this for a while, it's outside the scope of nvm. Nvm is used to install and switch between versions of node manually. There is an automatic default version, but I really want to keep the tool simple.
I do think it would be a great project for someone to create a new tool written in node.js that looks at the package.json files in the current working tree and outputs the ideal node version to run. This tool will need to be installed somewhere outside nvm's tree and in your $PATH so that it will stay in scope as you switch between node versions. It can use #!/bin/env node
in it's shebang. JSON parsing and file reading API's haven't changed in node in a long time, so it should run in nearly any version you want to use.
@creationix No pb for me, the ruby code can easily be ported to js so I'll give it a try when I can find some spare time.
It will be a cool thing to have!
I would pay 2$ if somebody implements this feature.
@potomak you'll pay someone to write a patch I've said I won't accept, or pay someone to write a separate utility as I suggested? (If it's the first, you'll just have to maintain a fork to keep the patch. there won't be hurt feelings)
@creationix the best would be to get this patch merged inside your repo (note I'd give part of that bounty to you as the maintainer of the project) but I could pay also for the second solution.
@creationix plugin nag : )
The .nvmrc
is already read when calling nvm use
, so what is the point of this issue? Or is it me being ignorant right now?
@koenpunt right, I was talking about parsing package.json in nvm. That's outside the scope of the project.
I didn’t even know about the .nvmrc
file. That’s good enough for me.
@creationix Have you considered something like this?
nvm use $(node -e 'console.log(require("./package.json").engines.node)')
That doesn't work if the engine is defined as >=0.4.0
..
@koenpunt , depending on the semantics you desire, you can use something like this if you want to use the least-recent supported version in package.json
nvm use $(node -e 'console.log(require("./package.json").engines.node.replace(/[^\d\.]+/g, ""))')
That's not the only exception, see https://npmjs.org/doc/json.html and https://github.com/isaacs/node-semver
Version range descriptors may be any of the following styles, where "version" is a semver compatible version identifier.
version
Must matchversion
exactly=version
Same as justversion
>version
Must be greater thanversion
>=version
etc<version
<=version
~version
See 'Tilde Version Ranges' below1.2.x
See 'X Version Ranges' belowhttp://...
See 'URLs as Dependencies' below*
Matches any version""
(just an empty string) Same as*
version1 - version2
Same as>=version1 <=version2
.range1 || range2
Passes if eitherrange1
orrange2
are satisfied.git...
See 'Git URLs as Dependencies' below
@koenpunt useful tip. It would be nice if this is automatically called after navigating to the folder that containing .nvmrc
@activars you'd have to patch "cd" for that, which is far outside of the scope of nvm :-)
I've written the following shell script, which depends on the semver
module to pick exactly the perfect node version (latest version possible, as allowed by the engines field):
function getFromPackage () {
$(which node) -e "console.log(require('./package.json').${1})";
if [ "$?" != "0" ]; then
echo "Not found in package.json: $1";
exit 1;
fi
}
node () {
nvmPath="/nvm";
semverPath="$nvmPath/v0.8.25/bin/semver";
range=getFromPackage('engines.node');
nodeVersions=$(find "$nvmPath" -maxdepth 1 -type d -name 'v*' -printf '%f\n');
if [ "${nodeVersions}" = "" ]; then
echo "No installed Node.js versions could be found in $nvmPath";
return 1;
fi;
nodeVer=$($semverPath --range "$range" $nodeVersions | tail -1);
if [ "${nodeVer}" = "" ]; then
echo "No installed Node.js versions match range '${range}'";
return 1;
fi;
(nvm use $nodeVer > /dev/null 2>&1 && $(which node) $*);
ret=$?;
tset;
return $ret;
}
I'm sure it's not perfect, but could be the basis for something better? Feedback encouraged :)
This is very important. As let say I only want to run with versoin 0.11.2 not higher. E.g if I run with a higher version of node my database data could get corrupted. An 'nvmrc' implementation would prevent this.
@denysonique If that's the case you should probably do some version checking in your app..?
@denysonique Odd versions of node are unstable. You shouldn't be using them with production data, ever.
Quick Fix: IF YOU USE rvm already... or you just just have it installed:
- Create an .rvmrc file
touch .rvmrc
subl .rvmrc
- type
nvm use 0.11
- save
- Go up
cd ..
and go in the your folder.
RVM will execute it anyways.
@intuivo in this case, I prefer to use autoenv https://github.com/kennethreitz/autoenv
@creationix I think that feature would be very welcome to NVM and I still think that it wouldn't make NVM more complex at all.
It's also useful for each CI environment as well. so that each project in the CI are isolated automatically by nvm.
@activars #truestory :+1:
@activars to quote myself:
The
.nvmrc
is already read when callingnvm use
, so what is the point of this issue? Or is it me being ignorant right now?
So in a CI environment you would only have to run nvm use
to have the correct node environment.
@activars the point of using the .nvmrc like .rvmrc is that you don't need to run any other command to make it work. When go inside of your project's folder RVM automatically loads the correct ruby version based on the .rvmrc file... no need to run nvm use.
nvm use
is nice but it could be nicer if it could work like rvm/rbenv/pyenv already does.
This is because rvm
patches cd
, which I don't like. And rbenv
creates so called "shims" which load the environment. Which could be an option, create ~/.nvm/bin/node
which detects if there is a .nvmrc
file in the current directory.
But this would mean these "shims" have to be created for every binary like coffee
, grunt
, lesscss
I quite like the shin approach.
Sent from my iPhone
On 15 Apr 2014, at 18:28, Koen Punt notifications@github.com wrote:
This is because rvm patches cd, which I don't like. And rbenv creates so called "shims" which load the environment. Which could be an option, create ~/.nvm/bin/node which detects if there is a .nvmrc file in the current directory.
But this would mean these "shims" have to be created for every binary.
— Reply to this email directly or view it on GitHub.
rbenv
-style shims and patching cd
are far outside the scope of this project, and won't happen.
Let's all please stop providing additional plus ones - If anyone wants to open a PR, or file an issue, for a very tightly focused and small way that nvm
can utitilize .nvmrc
, I'm happy to consider it - see #318 - but this issue will remain closed.
I think what some of the commenters here are missing is that this project team isn't saying the solution shouldn't exist. They're saying that it shouldn't be part of this project.
There's nothing prohibiting someone from creating a tool, auto-nvm-env
, that reads .nvmrc
(or .node_version
to mirror rvm
's support for .ruby_version
). In fact, it sounds like that's what they'd encourage.
@wbyoung I can't see why it shouldn't be part of NVM but ok... you already made a decision 2 years ago ;-)
It would be nice if we had a ".nvmrc" file for a project, kind of like ".rvmrc" for ruby. I'll start prototyping this later. What do you guys think?