Any tools for deducing the Node version from package-lock.json?

165 Views Asked by At

I recently come with dealing with the front-end projects, and I've cloned some repos but I don'n see the correct version needed for the project.And if I use my own version of node, it may give me warning like npm WARN old lockfile and npm WARN EBADENGINE due to the wrong version usage of node and npm.After some search, I think it's better to support correct engine in package.json file, but I don't see that in the repo so I have to try to run the npm update --package-lock-only or npm install --package-lock-only continuously to get the appropriate version. But after I check the package-lock.json, I see some engines for different packages so I'm wondering whether there is any tools for deducing the appropriate version from the file?

"node_modules/@achrinza/node-ipc": {
                        "version": "9.2.2",
                        "resolved": "https://registry.npmmirror.com/@achrinza/node-ipc/-/node-ipc-9.2.2.tgz",
                        "integrity": "sha512-b90U39dx0cU6emsOvy5hxU4ApNXnE3+Tuo8XQZfiKTGelDwpMwBVgBP7QX6dGTcJgu/miyJuNJ/2naFBliNWEw==",
                        "dev": true,
                        "dependencies": {
                                "@node-ipc/js-queue": "2.0.3",
                                "event-pubsub": "4.3.0",
                                "js-message": "1.0.7"
                        },
                        "engines": {
                                "node": "8 || 10 || 12 || 14 || 16 || 17"
                        }
                },
                "node_modules/@ampproject/remapping": {
                        "version": "2.2.1",
                        "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz",
                        "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
                        "dev": true,
                        "dependencies": {
                                "@jridgewell/gen-mapping": "^0.3.0",
                                "@jridgewell/trace-mapping": "^0.3.9"
                        },
                        "engines": {
                                "node": ">=6.0.0"
                        }
                },
2

There are 2 best solutions below

3
adsy On

There are two separate issues at hand here. Firstly there is the issue of the lockfile, and what version of NPM that lockfile was produced from, as opposed to your version of NPM. Secondly, there are the versions of Node that can be used with the project according to the projects engines constraints (where defined, and including subdependencies).

These two "issues" are essentially unrelated.

Lockfile version

If you check out a project that has a lock file produced with an older version of NPM than what you have installed and run npm install, you may encounter the npm WARN old lockfile message. It's generally not necessary to use the exact version of NPM that the lockfile was produced from. Instead, you would usually:

  • Ignore the warning, since NPM is backwards compatible. It is highly unlikely using a newer version of NPM will cause an issue. Perhaps encourage the repo owner to update their version of NPM and commit the new lockfile.
  • Fork it, update the lockfile once and commit that updated lockfile yourself.

Engine constraints

Typically, the best version of Node to run is simply the latest one (or the latest LTS). It is fairly rare for a package to work on a previous version of Node and not the newest, because Node aims to be backwards compatible. Node version is generally a much smaller concern than in other languages like Java when it comes to backwards compatibility.

However, in your snippet, you have identified a package that has the range 8 || 10 || 12 || 14 || 16 || 17. This means the author of that package has made the (unusual) choice to suggest the package can only be used on a certain set of versions as opposed to declaring >= 8. Unfortunately, this is often because of an overzealous package author. It is quite likely, that the package works fine on the latest node. Nonetheless, for such packages, they are usually updated (if they are maintained) to expand the version list. That is the case for that package. It is notable that the commit that added a new version to this list was just the package.json changes, and no code changes. Which increases the likelihood that it's simply an overly constrained range.

It's probably fine to ignore the warning for these cases. It should be tested of course.

However, if you want to be strict about this you would:

  • Use latest node (or node LTS depending on preference).
  • Upgrade the project dependencies using npm outdated or similar.
  • Commit the newly modified lockfile.
  • The warning may be gone now. For any packages that still warn, raise a ticket/PR for that package to update its version constraints, but probably use it anyway in the meantime.

Whilst you could write some script to find the node version that satisfies all the engine constraints, I feel doing this leads you into a false sense of security. On older repos which depend on old packages, there will be packages with unnecessarily strict engine constraints. Adhering to them religiously could mean you unnecessarily use an older and unsupported version of node.

1
Allison Pike On

I'm biased, but my startup Infield is designed to solve exactly this problem. We have a tool called Upgrade Path where you input your current version of a given package, a target version, and Upgrade Path runs a solver algorithm over the set of your dependencies to tell you which packages are compatible, which need to be upgraded, and in what order. We can do this because we've ingested all the changelogs and categorized version compatibility and breaking changes, so we match this against your lock file. We only support JS via NPM so it would work in your case. You're welcome to try it out or check out the docs here: https://docs.infield.ai/docs/using-upgrade-path