How do I install NPM packages while ignoring semvar? - npm

I'm having a problem where some recent update (in the last week) to a dependency of a dependency is causing a breaking error in Safari. I have all of my versions set to exact in package.json but their dependencies are obviously going to pull using semvar version ranges. My old package-lock.json has invalid checksums now so that isn't working.
How do I rebuild my node_modules using the lowest specified versions of dependencies (ignoring semvar/version ranges)? I want to get the exact specified packages for all dependencies without automatically pulling a more recent version.

By way of example: foo" = "~1.0.1,

Related

How to update a specific npm package dependency version without updating all occurences?

npm ls ansi-regex shows the following, ansi-regex is used is loads of other places also. I need to get this version to 3.0.1 at least due to security issue.
I've tried adding chalk to package.json but version shown persists. Adding ansi-regex version I need to package.json doesn't affect this dependency tree either, same applies to has-ansi and strip-ansi, seems to be locked to chalk#1.1.3. ansi-regex is present as a dependency in many places in the app and I tried npm-force-resolutions but it seems to do a blanket update which I don't want. Any advice?

Update dependencies on package.json based on package-lock.json

After almost a day of battle with discrepancies between package.json based on package-lock.json I finally made my project to run again (on Node 10) and I want to keep it in that way.
I want to update my package.json to contain the versions listed in package-lock.json. Is there an automatic way to do this? I can find any about it (or maybe I am looking for the wrong keywords)

npm default dependency specificity

In package.json, if I specify a dependency such as
"react": "~16.1.1"
This allows NPM to change the patch version only, i.e. it may use version 16.1.2, but it will not use version 16.2.X
Similarly, if I specify a dependency such as
"react": "^16.1.1"
This allows NPM to change the minor version only (the middle number).
But what if I don't have any character in front of the dependency version, e.g.
"react": "16.1.1"
Does this mean that only version 16.1.1 can be used?
By "Pinning" your projects dependency in package.json, (i.e. specifying a semver without a caret or tilde range specifier), will result in a "similar" version being installed each time.
Given the example of; "react": "16.1.1" specified in your package.json, this will result in version 16.1.1 of react being installed each time npm install is run.
However, (notice that I put emphasis on the word "similar"), this does not mean to suggest that by "pinning" you will get all the "exact same" files that constituted to the react package version 16.1.1 when your packages were last installed. The reason for this is the react dependencies specified in its package.json utillize a combination of caret and tilde range specifiers. So the versions of those dependencies are subject to change. Likewise, the dependencies of those dependencies and so on, (aka: the dependency tree), are subject to change too.
Checkout npm-shrinkwrap and/or npm-package-locks if you're wanting to truly lock down the dependency versions tree for publication purposes.

NPM5, What is the difference of package-lock.json with package.json?

After updating NPM to version 5, I found package-lock.json file with package.json.
What is the difference between this two files?
What are the advantages of package-lock.json?
A package.json file: lists the packages that your project depends on. allows you to specify the versions of a package that your project can use using semantic versioning rules.
According to the npm docs,
package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json . It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.
This file is intended to be committed into source repositories, and serves various purposes:
Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.
Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself.
To facilitate greater visibility of tree changes through readable source control diffs.
Basically package-lock.json is used to optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.
Before npm 5.x.x, package.json was the source of truth for a project. What lived in package.json was law. npm users liked this model and grew very accustomed to maintaining their package file. However, when package-lock was first introduced, it acted contrary to how many people expected it to. Given a pre-existing package and package-lock, a change to the package.json (what many users considered the source of truth) was not reflected in the package-lock.
Example: Package A, version 1.0.0 is in the package and package-lock. In package.json, A is manually edited to version 1.1.0. If a user who considers package.json to be the source of truth runs npm install, they would expect version 1.1.0 to be installed. However, version 1.0.0 is installed, despite the fact that v1.1.0 is listed is the package.json.
Example: A module does not exist in the package-lock, but it does exist in the package.json. As a user who looks to package.json as the source of truth, I would expect for my module to be installed. However since the module is not present in package-lock, it isn’t installed, and my code fails because it cannot find the module.
Read more about package-lock.json in the Official npm Documentation!
package.json records only your direct dependencies and their versions.
package-lock.json records not only your direct dependencies and exact versions, but also those of all dependencies of your dependencies - the entire dependency tree, in other words, with exact versions.
It's the fact that package-lock.json records the exact versions of all dependencies of a project, including sub-dependencies, that ensures that builds will be identical each time. (This is why npm ci bases its build on package-lock.json, not package.json.)
Builds based on package.json (as with npm i) cannot guarantee that all sub-dependencies are the exact same versions each build (e.g., if the subdependency of one of your dependencies releases an update, but the version of your direct dependency doesn't change), even if exact version numbers for direct dependencies are specified in the package.json.

Renaming a published NPM module

Is there any way to rename an NPM module that has already been published? I want to change the name of my module to more accurately match the API it exposes but would not like to leave people who have already installed it in the lurch.
There isn't any exposed way to do that. When I've encountered this in the past the approach I took was:
npm deprecate %ProjectName%#"<=put-latest-version-here" "WARNING: This project has been renamed to %NewProjectName%. Install using %NewProjectName% instead."
npm Deprecate instructions
In simple words no you can't. But npm provides you a different solution called npm deprecate.
What it does is it marks a particular version or version ranges of that package as deprecated. So next if someone tries to install this package they get a warning package deprecated along with your custom message, in which you can easily specify your new package name.
Usage:
npm deprecate my-package-name#"< latest-version" "your message"
Your message can be any thing like:
WARNING: This project has been renamed to your-new-package-name. Install using new-package-name instead.
In less than 24 hours i ran following command to delete wrong package.
npm unpublish <wrong package name> --force
From the documentation:
Registry data is immutable, meaning once published, a package cannot
change. We do this for reasons of security and stability of the users
who depend on those packages.
However newly published packages - within 72 hours - can be unpublished by running:
npm unpublish <package_name> -f
This will remove the package from the NPM registry if it was published less than 72 hours ago. Then you can change your package's name and publish it again.
Caution: You need to wait 24 hours if you try to republish package
with the same name
Someone has built a handy little npm plugin for doing this easily 😊
https://www.npmjs.com/package/#tiaanduplessis/pkg-rename
Install the package using npm -g install #tiaanduplessis/pkg-rename
Rename your npm module in the package.json file and save it
run pkg-rename old-package-name
From the documentation:
This will get the latest version of the old package from npm and deprecate this and all previous published versions with a message:
WARNING: This project has been renamed to new-package-name. Install using new-package-name instead.
You can also add the --publish flag to publish the new package name as part of the same action.
pkg-rename old-package-name --publish
Remember, rename the package in package.json first, then run the pkg-rename command.
I once was in this situation. I published a package with the name bowser-or-node instead of browser-or-node.
There's no way to rename a package, you have to deprecate and publish a new package.
Although there's one other option. If you just published your package (less than 24 hours from time of publish) and if you're sure you're okay with deleting the package and publish a new one with the right name, you can go ahead and do it. But NPM won't allow you to delete the package once it's been 24 hours since the time of publish.
Fortunately I figured out that I published with the wrong name in less than 20 minutes. So I just deleted and published again with a new name.
Something marvelous just happened to me: I managed to rename a package. It was originally known as stdout-renderer, but I changed every possible occurence of the name, and republished it after having deprecated the original and voila it shows up under its new name (cli-artist) undeprecated in the newly updated list. I'm not sure which field to change, but I would imagine it be in package.json because that's the only one where the casing matched in my case.
hope that helps!