Femto is CLI tool that manages the npm packages used by Fable bindings.
dotnet tool install femto --global
Project Dependency Analysis
cd your way to the directory where you have your Fable application and run
Alternatively, you can specify a project file by yourself:
Here is an example output:
c:\projects\elmish-getting-started\src> femto [18:17:09 INF] Analyzing project c:/projects/elmish-getting-started/src/App.fsproj [18:17:11 INF] Found package.json in c:\projects\elmish-getting-started [18:17:11 INF] Using npm for package management [18:17:14 INF] Elmish.AnimatedTree requires npm package react-spring [18:17:14 INF] | -- Required range >= 8.0.0 found in project file [18:17:14 INF] | -- Used range ^8.0.1 in package.json [18:17:14 INF] | -- Found installed version 8.0.1 [18:17:14 INF] | -- react-spring was installed into "devDependencies" instead of "dependencies" [18:17:14 INF] | -- Re-install as a production dependency [18:17:14 INF] | -- Resolve manually using 'npm uninstall react-spring' then 'npm install email@example.com --save' [18:17:14 INF] Fable.DateFunctions requires npm package date-fns [18:17:14 INF] | -- Required range >= 1.30 < 2.0 found in project file [18:17:14 INF] | -- Missing date-fns in package.json [18:17:14 INF] | -- Resolve manually using 'npm install firstname.lastname@example.org --save' [18:17:14 INF] Elmish.SweetAlert requires npm package sweetalert2 [18:17:14 INF] | -- Required range >= 8.5 found in project file [18:17:14 INF] | -- Missing sweetalert2 in package.json [18:17:14 INF] | -- Resolve manually using 'npm install email@example.com --save'
Automatic Package resolution with
Femto can automagically resolve required package issues using the command
femto --resolve femto --resolve ./src/Client.fsproj
This command checks for missing packages and packages of which the installed version does not satisfy the required version found in npm dependency metadata of the used Fable packages.
- If a package is missing then it is installed.
- If a package version doesn't satisfy requirements, then a proper version is resolved and the package is replaced with the new resolved version by uninstalling the current one and installing the correct package.
- If a package version doesn't satisfy requirements and a version cannot be resolved that satisfies requirements, then a resolution error is logged.
In order for Femto to pick up the npm packages that your library depends upon, you must add a section in the project file of your library:
<PropertyGroup> <NpmDependencies> <NpmPackage Name="date-fns" Version=">= 1.30.0" /> </NpmDependencies> </PropertyGroup>
Notice here in the example, we have one npm package we depend upon which has requires a version that satisfies that range
>= 1.30.0. If the user doesn't have that version installed or has an old version, a message will appear telling them how to solve the issue.
You can customize the resolution strategy by adding
ResolutionStrategy attribute to an
NpmPackage node. Accepted values are
max (case-insensitive). If
ResolutionStrategy is not set, we default to
<PropertyGroup> <NpmDependencies> <NpmPackage Name="date-fns" Version=">= 1.30.0" ResolutionStrategy="max" /> </NpmDependencies> </PropertyGroup>
You can specify whether the npm package your library depends upon is actually a development dependency instead a production dependency using the
DevDependency attribute. Package resolution take development dependencies into account and if the developer had installed the package by mistake in production dependencies then the automatic resolver will un-install it and re-install it a development dependency.
<PropertyGroup> <NpmDependencies> <NpmPackage Name="date-fns" Version=">= 1.30.0" DevDependency="true" /> </NpmDependencies> </PropertyGroup>
Unsupported Version Ranges
Sometimes you want to restrict the version using a specific range such as
>= 1.0 < 2 This range cannot be set inside the attribute value of
Version because the XML would be invalid and you would not be able to
dotnet restore the project. In these cases you can replace the operator with it's abbreviated name:
This way you can specify your version range as
gte 1.0 lt 2 or you can mix-and-match the notations
>= 1.0 lt 2
Validate your dependencies
If you are a library author and wondering whether Femto will pick uo the dependencies you specified in your project file, then simply run:
femto --validate femto --validate ./path/to/Library.fsproj
In the directory where you have the project file of your library. This command will check whether the library has valid metadata about the required npm packages and will try to resolve the versions based on the specified