3

I have a Node app that is tested on node 10. I am using yarn as a dependency manager. As my app test is run on CI with the latest version of node 10, I want to make sure that all developers have installed the latest 10.x.x version when running any yarn command.

For example, let's say the current latest node version is 10.22.1, then I want to stop the yarn install if the developer is on 10.22.0 or 10.11.1.

Using the engine directive in package.json I tried the following syntax but no avail.

{
  "engines": {
    "node": "^10.x.x",
  }
}
{
  "engines": {
    "node": "^10",
  }
}
{
  "engines": {
    "node": ">10.0.0 <11.0.0",
  }
}
{
  "engines": {
    "node": "10",
  }
}

All of these allow any node with major version 10.

Mayank Patel
  • 8,088
  • 5
  • 55
  • 75
  • I'm a bit confused by the version restriction you want to impose. If I understand correctly you want to restrict it to the latest available 10.x.x release version of node? As far as I can tell, the `engines` section is unrelated to the latest release of node, it just allows for a version restriction check on a hard-coded version (range) you define with it. – stvn Sep 07 '20 at 19:16
  • I am okay with any other way to do it either. The yarn's `engine` setting seemed to do something very close to it. It makes sure that the engine is more than 10.x.x but I want to make sure it is the latest eligible 10.x.x. – Mayank Patel Sep 07 '20 at 19:28
  • I'm just saying that if you want to compare with the actual latest version of node, you will have to add some more custom scripting to fetch the actual latest version online, etc. This could also add a possible disconnect between the latest version of node and the node version installed on your CI server. A more simple approach would be to restrict to a fixed version in your package.json manually and update that version from time to time. – stvn Sep 07 '20 at 19:43
  • "engines" set the required node version for your npm app, not for yarn. Also yarn could be global. Did you solve your problem? – JRichardsz Sep 08 '20 at 03:12
  • Yarn detects and verify the engine as well @JRichardsz. https://classic.yarnpkg.com/en/docs/package-json/#toc-engines – Mayank Patel Sep 08 '20 at 09:43

2 Answers2

0

As per the yarn documentation (https://classic.yarnpkg.com/en/docs/package-json/), the preinstall is called before the package is installed.

If defined, the preinstall script is called by yarn before your package is installed.

So I would go with something like this in your package.json:

"scripts": {
....
    "preinstall": "./scripts/preinstall.sh",
    
  }

Your preinstall.sh could be:

#!/bin/bash
currentver="$(node -v)"
requiredver="v10.0.0"

if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then 
        echo "Version is good so let's go with install"
else
        echo "Please install the node version greater than v10.0.0"
        exit -1
fi
 

So if your developer has a version less than v10.0.0, the above script will fail and will in turn fail the yarn install command.

Note: Credit to https://unix.stackexchange.com/questions/285924/how-to-compare-a-programs-version-in-a-shell-script for shell script for version comparison.

manishg
  • 9,520
  • 1
  • 16
  • 19
  • Checking and comparing for the minimal required node version can be done by setting the engine alone. https://classic.yarnpkg.com/en/docs/package-json/#toc-engines – Mayank Patel Sep 08 '20 at 09:45
  • But I see your point that I can retrieve the latest node version dynamically set it to `requiredver`. I was hoping for a method that is easier than this. – Mayank Patel Sep 08 '20 at 09:47
  • @MayankPatel - there is no built in mechanic where yarn fetches the latest version to compare with. I would also try go get the "latest node version installed on your CI server" instead of just taking the "latest available version of node" if you really want to go with this approach. In the end, you're really will be putting a lot of effort in this while I'm quite sure that manually restricting it to mayor/minor versions would be the more pragmatic solution. – stvn Sep 08 '20 at 10:28
  • I get your point @stvn. Planning to just use the latest node version wherever possible but make sure we have minimal version being used which I can change from time to time. – Mayank Patel Sep 09 '20 at 20:05
0

As we have in the npm doc :

to specify acceptable version ranges up to 1.0.4, use the following syntax:

  • Patch releases: 1.0 or 1.0.x or ~1.0.4
  • Minor releases: 1 or 1.x or ^1.0.4
  • Major releases: * or x

So, if you want to ask for only the 10.22.1 version or newer you should use ~10.22.1 or ^10.22.1

And it's another option to pin the version (you can read more about it from this link) by using the exact version like:

{
  "engines": {
    "node": "10.22.1",
  }
}
marzzy
  • 706
  • 10
  • 21