Add a new command (say `use`) to switch to preinstalled versions of Node.js
trivikr opened this issue · comments
Is your feature request related to a problem? Please describe.
There's no command for switching to specific pre-installed version of node.
The install command attempts to install latest semver version of requested version
Output on CodeBuild when command n 14
was run.
[Container] 2023/09/19 01:23:57 Running command n 14
curl: (28) Failed to connect to nodejs.org port 443 after 260269 ms: Couldn't connect to server
Error: failed to download version index (https://nodejs.org/dist/index.tab)
[Container] 2023/09/19 01:28:18 Command did not exit successfully n 14 exit status 2
[Container] 2023/09/19 01:28:18 Phase complete: INSTALL State: FAILED
[Container] 2023/09/19 01:28:18 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: n 14. Reason: exit status 2
Describe the solution you'd like
Add a new command (say use
) which just switches to preinstalled version
$ n use 14
Describe alternatives you've considered
- Switch to fnm
- Catch errors and retry using shell:
for i in {1..5}; do n 14 && break || sleep 15; done
Additional context
We use n in release CI. And the installation used to fail sometimes because of 4XX from Node.js website.
We switched to creating a Docker Image for preinstalling Node.js versions, but noticed that Node.js website is still accessed when n attempts to switch to preinstalled versions.
Steps to repro
Install with network on
$ n 14
installing : node-v14.21.3
mkdir : /usr/local/n/versions/node/14.21.3
fetch : https://nodejs.org/dist/v14.21.3/node-v14.21.3-darwin-x64.tar.xz
copying : node/14.21.3
installed : v14.21.3 (with npm 6.14.18)
Test with network off
$ n 14
curl: (6) Could not resolve host: nodejs.org
Error: failed to download version index (https://nodejs.org/dist/index.tab)
Testing with fnm
$ fnm --version
fnm 1.35.1
Install with network on
$ fnm install 14
Installing Node v14.21.3 (x64)
Use with network off
$ node -v
v16.20.2
$ fnm use 14
Using Node v14.21.3
$ node -v
v14.21.3
Testing with nvm
$ nvm --version
0.39.5
Install with network on
$ nvm install 18
Downloading and installing node v18.18.0...
...
Now using node v18.18.0 (npm v9.8.1)
Creating default alias: default -> 18 (-> v18.18.0)
Use with network off
$ node -v
v16.20.2
$ nvm use 18
Now using node v18.18.0 (npm v9.8.1)
$ node -v
v18.18.0
A quick reply.
n
requires the network to resolve a partial version or alias. You can install a previously downloaded version without accessing the network by specifying the full version number, like n install 18.16.0
.
For an interactive install, running n
gives you a menu of the downloaded versions. n ls
lists the downloaded versions.
(There have been a few issues mentioning doing lookups against the local versions, I'll look for some later.)
You can install a previously downloaded version without accessing the network by specifying the full version number, like
n install 18.16.0
The full version number is not available in our release CI.
We install latest version of Node.js in Docker Image, and specify just the major version when running the CI.
The CI doesn't have access to the full version number installed. It just wants to use the preinstalled version from Docker image.
With current code, you would do something like this to install latest version available in the docker container (no error checking):
VERSION=$(n ls | tail -n 1)
n $VERSION
Verified that the workaround (with grep for major version) works when there's no internet
Install with network on
$ n 20
installing : node-v20.7.0
mkdir : /usr/local/n/versions/node/20.7.0
fetch : https://nodejs.org/dist/v20.7.0/node-v20.7.0-darwin-arm64.tar.xz
copying : node/20.7.0
installed : v20.7.0 to /usr/local/bin/node
$ node -v
v20.7.0
With network off
$ n 20
curl: (6) Could not resolve host: nodejs.org
Error: failed to download version index (https://nodejs.org/dist/index.tab)
$ n $(n ls | grep /20 | tail -n 1)
copying : node/20.7.0
installed : v20.7.0 (with npm 10.1.0)
It would be awesome if this workaround can be added as a new command (like use
) which can be called directly.
It would be awesome if this workaround can be added as a new command (like
use
)
The functionality requested
$ n --help
...
n <version> Install Node.js <version> (downloading if necessary)
n install <version> Install Node.js <version> (downloading if necessary)
n use <version> Switch to pre-installed Node.js <version>
...
The behavior when the version is installed
$ n use 18
copying : node/18.18.0
installed : v18.18.0 (with npm 9.8.1)
The behavior when version is not installed, can be similar to that of fnm, i.e. interactive
$ n use 18
Can't find an installed Node version matching v18.x.x.
Do you want to install it? answer [y/n]: y
installing : node-v18.18.0
mkdir : /usr/local/n/versions/node/18.18.0
fetch : https://nodejs.org/dist/v18.18.0/node-v18.18.0-darwin-arm64.tar.xz
copying : node/18.18.0
installed : v18.18.0 to /usr/local/bin/node
Although I quite like the clarity of a separate command (say use
) to parallel install
, it is by design limited to that one case. Many of the commands resolve a "version" by referring to index.tab
over network: run
, which
, exec
, and even rm
.
Other approaches could be an option to not use the internet (say --offline
), a prefix to refer to a downloaded version (say local/18
), or caching index.tab
for lookups. Thinking more about the prefix, probably limited to numeric versions as I don't think (say) local/auto
is sensible.
Added --offline
option in n
v9.2.0