- [#839](https://github.com/Schniz/fnm/pull/839) [`97be792`](https://github.com/Schniz/fnm/commit/97be792a4410d8f121e03a1f81f60c48cbfdee2c) Thanks [@amitdahan](https://github.com/amitdahan)! - Support resolving `engines.node` field via experimental `--resolve-engines` flag
> :rocket: Fast and simple Node.js version manager, built in Rust
> 🚀 Fast and simple Node.js version manager, built in Rust
<divalign="center">
<imgsrc="./docs/fnm.svg"alt="Blazing fast!">
@ -12,13 +12,13 @@
@@ -12,13 +12,13 @@
## Features
:earth_americas: Cross-platform support (macOS, Windows, Linux)
🌎 Cross-platform support (macOS, Windows, Linux)
:sparkles: Single file, easy installation, instant startup
✨ Single file, easy installation, instant startup
:rocket: Built with speed in mind
🚀 Built with speed in mind
:open_file_folder: Works with `.node-version` and `.nvmrc` files
📂 Works with `.node-version` and `.nvmrc` files
## Installation
@ -42,7 +42,7 @@ On other operating systems, upgrading `fnm` is almost the same as installing it.
@@ -42,7 +42,7 @@ On other operating systems, upgrading `fnm` is almost the same as installing it.
`--install-dir`
Set a custom directory for fnm to be installed. The default is `$HOME/.fnm`.
Set a custom directory for fnm to be installed. The default is `$XDG_DATA_HOME/fnm` (if `$XDG_DATA_HOME` is not defined it falls back to `$HOME/.local/share/fnm` on linux and `$HOME/Library/Application Support/fnm` on MacOS).
@ -96,9 +102,10 @@ Then, [set up your shell for fnm](#shell-setup)
@@ -96,9 +102,10 @@ Then, [set up your shell for fnm](#shell-setup)
- Download the [latest release binary](https://github.com/Schniz/fnm/releases) for your system
- Make it available globally on `PATH` environment variable
- Configure your shell profile:
- [Set up your shell for fnm](#shell-setup)
### Removing
To remove fnm (😢), just delete the `.fnm` folder in your home directory. You should also edit your shell configuration to remove any references to fnm (ie. read [Shell Setup](#shell-setup), and do the opposite).
## Completions
@ -114,7 +121,7 @@ Where `<SHELL>` can be one of the supported shells:
@@ -114,7 +121,7 @@ Where `<SHELL>` can be one of the supported shells:
- `bash`
- `zsh`
- `fish`
- `powershell`
- `power-shell`
Please follow your shell instructions to install them.
@ -122,9 +129,13 @@ Please follow your shell instructions to install them.
@@ -122,9 +129,13 @@ Please follow your shell instructions to install them.
Environment variables need to be setup before you can start using fnm.
This is done by evaluating the output of `fnm env`.
To automatically run `fnm use` when a directory contains a `.node-version` or `.nvmrc` file, add the `--use-on-cd` option to your shell setup.
> [!NOTE]
> Check out the [Configuration](./docs/configuration.md) section to enable highly
> recommended features, like automatic version switching.
Adding a `.node-version` to your project is as simple as:
```bash
$ node --version
v14.18.3
@ -165,17 +176,24 @@ Add the following to the end of your profile file:
@@ -165,17 +176,24 @@ Add the following to the end of your profile file:
- On Windows, the profile is located at `~\Documents\PowerShell\Microsoft.PowerShell_profile.ps1` or `$PROFILE`
- For macOS/Linux, the profile is located at `~/.config/powershell/Microsoft.PowerShell_profile.ps1`
- On Windows to edit your profile you can run this in a PowerShell
```powershell
notepad $profile
```
#### Windows Command Prompt aka Batch aka WinCMD
fnm is also supported but is not entirely covered. [You can set up a startup script](https://superuser.com/a/144348) and append the following line:
fnm is also supported but is not entirely covered. [You can set up a startup script](https://superuser.com/a/144348) and append the following lines:
```batch
FOR /f "tokens=*" %i IN ('fnm env --use-on-cd') DO CALL %i
@echo off
:: for /F will launch a new instance of cmd so we create a guard to prevent an infnite loop
if not defined FNM_AUTORUN_GUARD (
set "FNM_AUTORUN_GUARD=AutorunGuard"
FOR /f "tokens=*" %%z IN ('fnm env --use-on-cd') DO CALL %%z
)
```
⚠️ If you get the error `i was unexpected at this time`, please make a .cmd file as suggested by the first step in the Usage with Cmder secton add it's path to the `AutoRun` registry key.
#### Usage with Cmder
@ -183,18 +201,26 @@ Usage is very similar to the normal WinCMD install, apart for a few tweaks to al
@@ -183,18 +201,26 @@ Usage is very similar to the normal WinCMD install, apart for a few tweaks to al
Then you can do something like this:
- Make a .cmd file to invoke it
```batch
:: %CMDER_ROOT%\bin\fnm_init.cmd
@echo off
FOR /f "tokens=*" %%z IN ('fnm env --use-on-cd') DO CALL %%z
```
- Add it to the startup script
```batch
:: %CMDER_ROOT%\config\user_profile.cmd
call "%CMDER_ROOT%\bin\fnm_init.cmd"
```
You can replace `%CMDER_ROOT%` with any other convenient path too.
## [Configuration](./docs/configuration.md)
[See the available configuration options for an extended configuration documentation](./docs/configuration.md)
## [Usage](./docs/commands.md)
[See the available commands for an extended usage documentation](./docs/commands.md)
fnm comes with many features out of the box. Some of them are not activated by default as they’re changing your shell default behavior, and some are just a feature flag to avoid breaking changes or just experimental until we decide it is worthwhile to introduce them.
All these features can be configured by adding flags to the `fnm env` call when initializing the shell. For instance, if your shell set up looks like `eval "$(fnm env)"` then you can add a flag to it by changing it to `eval "$(fnm env --my-flag=value)"`
Here’s a list of these features and capabilities:
### `--use-on-cd`
**✅ Highly recommended**
`--use-on-cd` appends output to `fnm env`'s output that will hook into your shell upon changing directories, and will switch the Node.js version based on the requirements of the current directory, based on `.node-version` or `.nvmrc` (or `packages.json#engines#node` if `--resolve-engines` was enabled).
This allows you do avoid thinking about `fnm use`, and only `cd <DIR>` to make it work.
### `--version-file-strategy=recursive`
**✅ Highly recommended**
Makes `fnm use` and `fnm install` take parent directories into account when looking for a version file ("dotfile")--when no argument was given.
So, let's say we have the following directory structure:
```
repo/
├── package.json
├── .node-version <-withcontent:`20.0.0`
└── packages/
└── my-package/ <-Iamhere
└── package.json
```
And I'm running the following command:
```sh-session
repo/packages/my-package$ fnm use
```
Then fnm will switch to Node.js v20.0.0.
Without the explicit flag, the value is set to `local`, which will not traverse the directory tree and therefore will print:
```sh-session
repo/packages/my-package$ fnm use
error: Can't find version in dotfiles. Please provide a version manually to the command.
```
### `--enable-corepack`
**🧪 Experimental**
Runs [`corepack enable`](https://nodejs.org/api/corepack.html#enabling-the-feature) when a new version of Node.js is installed. Experimental due to the fact Corepack itself is experimental.
### `--resolve-engines`
**🧪 Experimental**
Treats `package.json#engines#node` as a valid Node.js version file ("dotfile"). So, if you have a package.json with the following content:
```json
{
"engines": {
"node": ">=20 <21"
}
}
```
Then:
- `fnm install` will install the latest satisfying Node.js 20.x version available in the Node.js dist server
- `fnm use` will use the latest satisfying Node.js 20.x version available on your system, or prompt to install if no version matched.