Is there any way to fix package-lock.json lockfileVersion so npm uses a specific format?
Asked Answered
R

9

285

If two different developers are using different versions of node (12/15) & npm (6/7) in a project that was originally created using a package-lock.json "lockfileVersion": 1, when the developer using npm 7x installs new packages it seems that the package-lock.json is re-created using "lockfileVersion": 2.

This seems to cause issues for the developer using npm v6, as it tries to work with the lockfileVersion 2, but it ends up producing new diffs.

npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was generated for lockfileVersion@2. I'll try to do my best with it!

Is there any way to specify to newer versions of npm to only use "lockfileVersion": 1? Or do we just have to get all devs on the same version of npm?

Retaliate answered 13/11, 2020 at 0:24 Comment(0)
A
156

Is there any way to specify to newer versions of npm to only use "lockfileVersion": 1? Or do we just have to get all devs on the same version of npm?

I will advise you to pin the Node/NPM version and align it across your environments (development, staging, and production).

you can leverage nvm for managing Node version by adding to your project .nvmrc file (don't forget to store it in your source control).

for instance, .nvmrc will look like:

$ cat .nvmrc
14.15.0

then, you can use nvm install && nvm use to use the pinned version of Node.

NPM also supports engines:

You can specify the version of node that your stuff works on:

{ "engines" : { "node" : ">=0.10.3 <0.12" } }

And, like with dependencies, if you don't specify the version (or if you specify "*" as the version), then any version of Node will do.

If you specify an "engines" field, then npm will require that "node" be somewhere on that list. If "engines" is omitted, then npm will just assume that it works on Node.

You can also use the "engines" field to specify which versions of npm are capable of properly installing your program. For example:

{ "engines" : { "npm" : "~1.0.20" } }

Unless the user has set the engine-strict config flag, this field is advisory only and will only produce warnings when your package is installed as a dependency.

When utilizing the engines field and make npm fail when the version constraints are unmet, set engine-strict=true (since it is false by default) in .npmrc file or as an npm_config_engine_strict=true environment variable

If set to true, then npm will stubbornly refuse to install (or even consider installing) any package that claims to not be compatible with the current Node.js version.

This can be overridden by setting the --force flag.

Another approach is to use a Docker container as a runtime environment for development and execution, which implies that you neither need to install Node, nor NPM. e.g.

$ mkdir my-project
$ cd my-project
$ docker run --rm -it -v $PWD:/app --entrypoint /bin/bash --workdir /app node:14.15.0
root@4da6ee3c2ac0:/app# npm init -y
Wrote to /app/package.json:

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}


root@4da6ee3c2ac0:/app# npm install
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] No description
npm WARN [email protected] No repository field.

up to date in 1.694s
found 0 vulnerabilities

root@4da6ee3c2ac0:/app# exit
exit
$ ls -x1
package-lock.json
package.json

As you can see, with neither Node, nor NPM:

  1. Created a new directory for a fresh project
  2. Spun up a Node Docker container, which comes with Node and NPM
  3. Created a new project (npm init -y)
  4. Exited the Docker container
  5. Listed the files within the working directory, where the container was spun

Since the docker run command above is long, you might wish to leverage docker-compose for a more streamlined workflow.

Anisometric answered 13/11, 2020 at 11:54 Comment(6)
heh i was hoping to avoid another .*rc file, but this is probably the real answer and the best wholistic solution to the underlying problem.Retaliate
@Ben: you can avoid another rc file in favor of docker-compose file ;) (i've updated my answer accordingly)Anisometric
I like nvm ls instead of catting the rc file. Gives you more info about what versions you have and which one is running. Easier to remember too, since most version managers have a similar command.Jinx
note that if you use npm and want to upgrade npm the easiest is nvm install-latest-npmSalmonoid
This doesn't enforce the npm version. Running nvm install && nvm use (with .nvmrc containing 12), will set npm to v6, however as soon as you install the latest version of npm on your laptop (npm install -g npm@latest), it gets updated for your nvm version too (nvm use now returns npm v8), thus you don't ensure consistency among your developers team.Rescript
@manuchaud100 as written,engine at the package.json should cover it. if not, i suggest to improve the answer.Anisometric
J
150

As of version 8.1.0 there is a flag --lockfile-version in npm with which you can override the default lock file version:

npm i --lockfile-version 3

You can also update/generate just the lock file without installing the dependencies by adding the flag --package-lock-only

npm i --lockfile-version 3 --package-lock-only

Here is the link to the original PR.

Jerald answered 28/10, 2022 at 17:37 Comment(2)
Obligatory "this should be the top answer" comment for anyone else coming across this question in the future.Schumann
Well, the OP is trying to solve issues caused by different developers using different versions of tools, but it seems like the bigger issue is that their dev environment isn't standardized in the first place (which is what the accepted answer talks about fixing). That's a big violation of the 12-factor app principles, not having parity between environments where your application is run: 12factor.net/dev-prod-parityHalpern
G
67

npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was generated for lockfileVersion@2. I'll try to do my best with it!

to overcome this issue, running the command

npm i -g npm@latest

globally and running the command

npm i npm@latest

in the project file helped me resolve the issue.

Gobi answered 21/7, 2021 at 6:7 Comment(6)
Did you do this in a linux system??Conard
Nope, in windows 10Gobi
OK thanks, i just restart my OS and this work's good.Conard
This npm i -g npm@latest worked for me. ThanksMeuse
In my case for Windows 10, I ran "npm i -g npm@latest" and also had to install the latest version of nodeJS (16.13.0).Typo
For most use cases, if installing locally - not globally - install as a dev dependency npm i npm@latest -DRose
E
29

As far as I can see the npm docs say that npm v6 will work with version 2 lockfiles in spite of the warning, so you don't need to do any of the things suggested in the accepted answer and can safely ignore the warning message.

In the npm 7 release notes they said:

One change to take note of is the new lockfile format, which is backwards compatible with npm 6 users. The lockfile v2 unlocks the ability to do deterministic and reproducible builds to produce a package tree.

In the npm docs it says (my emphasis):

lockfileVersion

An integer version, starting at 1 with the version number of this document whose semantics were used when generating this package-lock.json.

Note that the file format changed significantly in npm v7 to track information that would have otherwise required looking in node_modules or the npm registry. Lockfiles generated by npm v7 will contain lockfileVersion: 2.

  • No version provided: an "ancient" shrinkwrap file from a version of npm prior to npm v5.
  • 1: The lockfile version used by npm v5 and v6.
  • 2: The lockfile version used by npm v7, which is backwards compatible to v1 lockfiles.
  • 3: The lockfile version used by npm v7, without backwards compatibility affordances. This is used for the hidden lockfile at node_modules/.package-lock.json, and will likely be used in a future version of npm, once support for npm v6 is no longer relevant.

This is why they can automatically upgrade lockfiles from v1 to v2, which you mention, without breaking anything.

Elsieelsinore answered 7/6, 2021 at 15:7 Comment(3)
What we're seeing is that anyone that still has npm 6 and runs "npm install" in the project ends up with package-lock setting itself back to lockfileversion 1. Very annoying after we updated it to 2 with npm 7. Going to have to try one of the solutions, or get a bunch of devs to all update their machines promptly... haha.Pareto
Didn't realize npm 6 would downgrade it appropriately. package.json we have "engines": { .. } to lock in the node/npm range. Some flag allows npm to ignore this and still upgrade to lockfileVersion: 2. Best to keep npm & node versions in sync. Thanks Jeremy!Beamends
@JeremyL Disable package-lock.json in .npmrc with package-lock=false, and then manually run npm shrinkwrap every time you want to update your dependencies.Cyanosis
H
11

There is a much more simpler solution than using nvm:

npx [email protected] i --save

With this you can generate a new lockfile with version 1, use the latest node js version and you don't need to change anything on your machine.

Hacienda answered 16/6, 2022 at 14:38 Comment(2)
You're right.. This is the simpler solution.! Use npx to execute the task, and don't worry about local package versions. Thanks!Myosin
'nvm use stable'Infliction
I
6

I encountered the same problem today. I am working on a project with a developer having a different version of npm (>7) and i ran into the same issue. I simply upgraded my npm version to the latest version which was being used by the other developer as mentioned above. Following are the steps to upgrade your npm (for windows):

First, ensure that you can execute scripts on your system by running the following command from an elevated PowerShell. To run PowerShell as Administrator, click Start, search for PowerShell, right-click PowerShell and select Run as Administrator.

Next execute following commands:

Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force

Then, to install and use this upgrader tool, run the following command (also from an elevated PowerShell or cmd.exe). Note: This tool requires at least Node v8

npm install --global --production npm-windows-upgrade
npm-windows-upgrade

Want to just install the latest version? Sure:

npm-windows-upgrade --npm-version latest

Now you can select the version which you want to install from the command line.

https://github.com/felixrieseberg/npm-windows-upgrade

The above link is the tool which I've used. This tool is both for Linux/Windows. I hope it will help.

Implement answered 11/6, 2021 at 15:37 Comment(0)
R
0

lockfile construction depends on the npm version. v7+ will create lockfile 2, below will create lockfile v1.

Lockfile v2 is backwards compatible so people running npm < v6 will be ok to use it, but i am looking at a circleci build failure on my second screen which suggests some of the npm packages we use are not compatible with lockfile v2... i.e. old npm packages may not be as well maintained and compatible with lockfile v2.

Hence probably the best course of action is to dockerise and isolate your env.

This is why docker was invented! Get your project running in a docker container, then have a makefile command to build your project, maybe something like

.PHONY: up
up:
    $(MAKE) down
    docker-compose up -d
    $(MAKE) logs

With a compose file to setup your project, and then rely on make <insert command> to run / build your project. One command could be make shell to enter a shell environment where all your devs have the same npm / node versions. npm i -g npm@latest is not an answer as that just installs npm on wherever it is run, so new devs will still have to run that command unless its part of the build.

Remonstrance answered 28/7, 2022 at 9:56 Comment(0)
P
-1

I downloaded the latest nodejs from https://nodejs.org/en and it fixed my issue.

Psychosis answered 18/5, 2023 at 4:16 Comment(0)
W
-4

Try to remove package-lock.json and run npm install again.

Weeny answered 11/6, 2022 at 12:25 Comment(1)
It has nothing to do with regenerating your lock file. It has to do with the NPM version installed. You can generate the file 100 times with an older version of NPM, it will not make a difference.Caterinacatering

© 2022 - 2024 — McMap. All rights reserved.