upgrade a dependency of a global package in npm - node.js

npm version: 3.10.10
node version: 6.14.2
I need to upgrade some dependencies of npm to address some security warnings. An example: sshpk is a dependency of npm via http-signature and request:
bash-4.3# npm ls sshpk -g
/usr/local/lib
`-- npm#3.10.10
`-- request#2.75.0
`-- http-signature#1.1.1
`-- sshpk#1.10.1
I need sshpk to get upgraded to >=1.14.1, which is possible given the version lock in http-signature#1.1.1's package.json:
"dependencies": {
"assert-plus": "^0.2.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
},
I've tried running npm upgrade -g npm#3 and npm --depth 9999 upgrade -g npm#3 without any success. It seems that npm doesn't continue in any update action since it notices we're already on the latest npm 3.x.x release of 3.10.10. I need to be able to keep npm's dependencies up-to-date as far as security patches go. Is this possible through npm update directly? I'm thinking of something similar to yarn upgrade <package>#<version> where it will traverse a package's sub-dependencies and upgrade those, even if the parent package isn't in need of a version change.

A reliable way to reinstall the package is to remove it or node_modules and install again.
Since NPM cannot be installed without NPM, this requires Node to be reinstalled.
An alternative is to install a spare NPM wrapper (e.g. npm3) and use it to reinstall main npm package
npm i -g npm3
rm -rf npm/
npm3 i -g npm#3
--force option can be used to reinstall the package, but it doesn't guarantee that package dependencies will be reinstalled.

Related

How To Align package.json and package-lock.json When Dependency Versions Are Out of Sync?

Whats Happening
In Package.json:
"dependencies": {
...
"node-sass": "^4.13.0"
...
}
Run npm install
in package-lock.json:
"node-sass": {
"version": "4.13.1",
...
}
What I've Tried
1.
Deleting:
package-lock.json
node_modules dir
Then running npm install
2.
Deleting:
package-lock.json
node_modules dir
Then running npm install --cache /temp/empty-cache
3.
Deleting:
package-lock.json
node_modules dir
Then running npm update
Result: node-sass is not detected as updatable
4.
running npm install node-sass#4.13.1
This obviously works at syncing them both back up, but doesn't feel right as this could be happening to other dependencies without me knowing.
Questions
How do I get package.json and package-lock back in sync, without manually installing 4.13.1?
[Bonus] Why does 4.13.1 always get installed and used by package-lock.json?
[Bonus] Why does node-sass no get identified as needing an update?
[EDIT]
Would still love an answer for this, if anyone has one that doesn't involve manually updating the dependency
Those dependencies are exactly what you have configured:
in your package.json you defined ^4.13.0, the ^ means that you are fine installing the most recent version of that module with the major version of 4.
So when you run npm install you will install all the dependencies that match that semver range.
You can go deeper in semver.
If you want to lock the version you need to write "node-sass": "4.13.0" in your package.json and recreate the package-lock.json
Moreover, to install what is in the package-lock.json you need to run npm ci. If you run npm install you are updating your dependencies in your lock file (that will be updated)
How align package.json and package-lock.json where dependency versions are out of sync?
Regenerate the package-lock
Example:
npm init --yes
npm init fastify#2.0.0
// now package-lock has 2.0.0
rm -rf node_modules/
npm install
// now package-lock has 2.0.0 still
rm package-lock.json
npm install fastify#2.5.0 --no-save
npm install
// now package-lock has 2.5.0 (the version is loaded by node_modules tree)
rm package-lock.json
rm -rf node_modules/
npm install
// now package-lock has 2.11.0
So, if your files are out of sync "something" run the installation without using the lock file
this solved my issue
npm install --package-lock-only

Local grunt installation gives error

npm install -g grunt-cli //done successfully
npm install grunt --save --only=dev
gives following error
(node:11000) fs: re-evaluating native module sources is not supported. If
you are using the graceful
-fs module, please update it to a more recent version.
npm WARN prefer global coffee-script#1.10.0 should be installed with -g
project#1.0.0 C:\Users\Live\Desktop\node grunt\final
`-- (empty)
npm WARN project#1.0.0 No repository field.
npm ERR! code 1
Tried uninstalling grunt-cli, cleaning npm cache, then re-installing, but still the problem persists.
Ok short recap:
When in doubt remove your node_modules and install all packages again using npm install
If that didn't work, try updating your npm by executing npm update -g npm and redo step 1.
If that didn't solve your problem, try upgrading to another NodeJS version using nvm or n.

What NPM command should users run if the package.json file has been updated?

If I update the package.json file in an NPM workflow app, what command do existing users run to update their local node_modules dependencies?
To start using it, they run:
$ npm install
So what do they run if there is a change to the package.json file? Or do they just delete the folder and re-run the npm install command?
To re-validate the package.json and install adjusted versions or new packages:
$ npm install
The one thing this won't do is remove packages that aren't in package.json. To do that, run:
$ npm prune
If you've only changed package versions and not added new packages:
$ npm update
If you you've updated a specific package version:
$ npm update {packagename}
You should either do
npm install && npm prune
or
npm upgrade && npm prune
npm install will be faster than npm upgrade because it only updates packages in node_modules if package.json demands a newer version. npm uprade, on the other hand, will download updates to dependencies if they are available, which may include bug fixes. For ≥npm-5, you should use npm install because npm upgrade will have the side-effect of modifying any package-lock.json file which should not be modified unless if you are the package’s maintainer.
npm prune is necessary because the updates to package.json may have removed dependencies. If you do not run npm prune, packages installed by a prior version of package.json will remain in the node_modules directory that would not be there if you freshly downloaded/cloned the project and ran npm install. Due to how some packages conditionally call require() or even scan the node_modules directory, leaving packages which were removed from package.json can result in unexpected behavior.

How to install a previous exact version of a NPM package?

I used nvm to download node v0.4.10 and installed npm to work with that version of node.
I am trying to install express using
npm install express -g
and I get an error that express requires node version >= 0.5.0.
Well, this is odd, since I am following the directions for a node+express+mongodb tutorial here that used node v0.4.10, so I am assuming express is/was available to node v0.4.10. If my assumption is correct, how do I tell npm to fetch a version that would work with my setup?
If you have to install an older version of a package, just specify it
npm install <package>#<version>
For example: npm install express#3.0.0
You can also add the --save flag to that command to add it to your package.json dependencies, or --save --save-exact flags if you want that exact version specified in your package.json dependencies.
The install command is documented here: https://docs.npmjs.com/cli/install
If you're not sure what versions of a package are available, you can use:
npm view <package> versions
And npm view can be used for viewing other things about a package too. https://docs.npmjs.com/cli/view
It's quite easy. Just write this, for example:
npm install -g npm#4.6.1
Or:
npm install -g npm#latest // For the last stable version
npm install -g npm#next // For the most recent release
First remove old version, then run literally the following:
npm install express#3.X
or
npm install express#4.X
and for stable or recent
npm install -g npm#latest // For the last stable version
npm install -g npm#next // For the most recent release
In my opinion that is easiest and fastest way:
$ npm -v
4.2.0
$ npm install -g npm#latest-3
...
$ npm -v
3.10.10
you can update your npm package by using this command:
npm install <package_name>#<version_number>
example:
npm install yargs#12.0.2
You can use the following command to install a previous version of an npm package:
npm install packagename#version
I have a general way to solve this type of problems, which could be helpful too, especially when cloning repositories to run them locally, but requires a little more analysis of the versions.
With the package npm-check-updates I verify the versions of the packages (according to the package.json file) that are not declared in their latest available versions, as shown in the figure (https://www.npmjs.com/package/npm-check-updates):
With this information we can verify the update status of the different packages and make decisions as to which packages to upgrade / degrade and which ones do not.
Assuming that we decided to update all the packages as they are listed, we can use the ncu -u command which only modifies your package.json file. Run npm install to update your installed packages and package-lock.json.
Then, depending on the requirements of the repository, we can refine what is needed, installing the specific versions with
npm view <package> versions and npm install <package>#<version>
The easiest way I found: add package name with the version in package.json and then run npm install
"next-seo": "^5.4.0",
"next-themes": "^0.1.1",
"nextjs-progressbar": "^0.0.14",
If you have to install an older version of a package, just specify it
npm install #
For example: npm install express#3.0.0
You can also add the --save flag to that command to add it to your package.json dependencies, or --save --save-exact flags if you want that exact version specified in your package.json dependencies.
The install command is documented here: https://docs.npmjs.com/cli/install
If you're not sure what versions of a package are available, you can use:
npm view versions
And npm view can be used for viewing other things about a package too. https://docs.npmjs.com/cli/view
Use npm config set save-exact=true if you want to install the exact version

npm install vs. update - what's the difference?

What is the practical difference between npm install and npm update? When should I use which?
The difference between npm install and npm update handling of package versions specified in package.json:
{
"name": "my-project",
"version": "1.0", // install update
"dependencies": { // ------------------
"already-installed-versionless-module": "*", // ignores "1.0" -> "1.1"
"already-installed-semver-module": "^1.4.3" // ignores "1.4.3" -> "1.5.2"
"already-installed-versioned-module": "3.4.1" // ignores ignores
"not-yet-installed-versionless-module": "*", // installs installs
"not-yet-installed-semver-module": "^4.2.1" // installs installs
"not-yet-installed-versioned-module": "2.7.8" // installs installs
}
}
Summary: The only big difference is that an already installed module with fuzzy versioning ...
gets ignored by npm install
gets updated by npm update
Additionally: install and update by default handle devDependencies differently
npm install will install/update devDependencies unless --production flag is added
npm update will ignore devDependencies unless --dev flag is added
Why use npm install at all?
Because npm install does more when you look besides handling your dependencies in package.json.
As you can see in npm install you can ...
manually install node-modules
set them as global (which puts them in the shell's PATH) using npm install -g <name>
install certain versions described by git tags
install from a git url
force a reinstall with --force
npm install installs all modules that are listed on package.json file and their dependencies.
npm update updates all packages in the node_modules directory and their dependencies.
npm install express installs only the express module and its dependencies.
npm update express updates express module (starting with npm#2.x, it doesn't update its dependencies).
So updates are for when you already have the module and wish to get the new version.
In most cases, this will install the latest version of the module published on npm.
npm install express --save
or better to upgrade module to latest version use:
npm install express#latest --save --force
--save: Package will appear in your dependencies.
More info: npm-install
npm update: install and update with latest node modules which are in package.json
npm install: install node modules which are defined in package.json(without update)
Many distinctions have already been mentioned. Here is one more:
Running npm install at the top of your source directory will run various scripts: prepublish, preinstall, install, postinstall. Depending on what these scripts do, a npm install may do considerably more work than just installing dependencies.
I've just had a use case where prepublish would call make and the Makefile was designed to fetch dependencies if the package.json got updated. Calling npm install from within the Makefile would have lead to an infinite recursion, while calling npm update worked just fine, installing all dependencies so that the build could proceed even if make was called directly.

Resources