Sun Feb 26 2017
Paul Shan
If you install an npm
package my-package
globally in your computer and then change the version of node js using nvm; you won’t be able to access the my-package
from your global scope any more. The reason is, nvm install the global packages only for the current version of node js and doesn’t share them with other versions.
When you install a package globally (or even locally), you assume that package is compatible & tested with that version of node js. When you change the version of node, it has no guarantee that the previous module which you installed is compatible with the newer version. May be the package could have never be tested in that new version of node. Thus, nvm keeps the installed global packages specific to the versions of node. If a user needs some modules to be carry forwarded, he will either reinstall them or will use the --reinstall-packages-from
parameter.
I agree with the theory of nvm team. But developers are lazy. If I had to install the packages like grunt
, bower
again and again in different versions of node manually; it will certainly become a pain for me. So I personally feed to need of carry forwarding the global packages somehow.
One most talked way to have common global packages is by changing the NPM_CONFIG_PREFIX
environment variable. But this works completely against the nvm philosophy and also is not recommended by nvm team. I’ve also faced issues with this approach. So better to avoid this and go with the following way.
One of the easiest way to to use the globally installed packages is by using the --reinstall-packages-from
flag while installing the new node version. This approach is as simple as running the following code.
nvm install 7.6.0 --reinstall-packages-from=7.0.0
nvm use 7.6.0
The above way will help you reinstalling the packages at the time you install a new version of node js. But sometimes, you need to swap between versions too often. For an example I work both with ember-cli and angular-cli. Now ember-cli wants a node below 6.9 and angular-cli wants node to be greater than 6.9 version. So I often switch between two versions (6.2.1 & 6.9.5 in my case). Now if I install a global package in my 6.9.5 in some day and want that to be available on 6.2.1 when I switch the version; the above mentioned approach will not work, cause I installed 6.2.1 long ago.
To avoid this situation, the best thing could have been using --reinstall-packages-from
flag while doing nvm use
and not nvm install
. But unfortunately the flag is not available with use
command. So now a days I’m using the following bash to achieve my goal.
nvm_use (){
NODE_NEW=$1
PREVIOUS_PACKAGES=$(npm ls -g --parseable --depth=0)
nvm use ${NODE_NEW}
ALL_PACKAGES=$(npm ls -g --depth=0)
for PACKAGE in $(echo "$PREVIOUS_PACKAGES" | grep "/node_modules/[^npm]");
do
PACKAGE_NAME=${PACKAGE##*/}
PACKAGE_IN_CURRENT_VERSION=$(echo "$ALL_PACKAGES" | grep $PACKAGE_NAME)
if [ "$PACKAGE_IN_CURRENT_VERSION" = "" ]; then
npm i -g $PACKAGE_NAME
fi
done
}
You need to copy the code above and paste it in your .bash_profile
file and restart your terminal (or use source ~/.bash_profile
). Then you will be able to switch the versions using the following command.
nvm_use 7.6.0
This way it won’t attempt to install the packages again and again, but will certainly update the newly added packages.
I understand, this is no concrete approach, but a hack to solve our purpose.
SHARE THIS ARTICLE
Thu Mar 10 2016
OAuth authentications are pretty popular now a days and another thing which is popular is JavaScript. This article shows how to plugin google’s oAuth api for authentication in your own node application.Sat Mar 01 2014
This is a continuation of my CSS3 loader snippet collection series. I've provided spinning css3 animation loader in the part 1 of this series and here in part 2, I'm providing various square type loading