The project file¶
Unlike JS, F# projects require all sources to be listed in compilation order in an
.fsproj file. This may look quite restrictive at first, but it does have some advantages.
Since an F# project takes its roots from the .NET ecosystem, we need to follow a few obligatory steps in order to add a file to an F# project.
Many F# IDEs already provide commands to perform operations like creating a project or adding/removing a file. The steps below are only necessary if you want to do this manually.
Create an .fsproj file
.fsprojfiles are in XML format. This may look a bit old-fashioned, but luckily the basic schema for F# projects has become much simpler in recent versions. Now the skeleton for most projects looks like this:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <ItemGroup> <!-- List your source files here --> </ItemGroup> <ItemGroup> <!-- List your package references here if you don't use Paket --> </ItemGroup> </Project>
Add an .fs file to the project
F# source files end with the
.fsextension. To include a new one in the project, you only need to add it to the
.fsprojusing a relative path with the following tag:
<ItemGroup> <Compile Include="path/to/my/File.fs" /> <ItemGroup>
For example, if we have have an app with two files, named
App.fs(the last one contains the entry point), it will look like this
<ItemGroup> <Compile Include="MyAwesomeFeature.fs" /> <Compile Include="App.fs" /> <ItemGroup>
Please be aware that in F#, file order is important. For instance, if
MyAwesomeFeature.fs, then you must place
Let’s add another file,
Authentication.fs, located in another folder
Sharedwhich is at the same depth as our
srcfolder (this can happen, for example, if the file is shared with another project, like a server). Let’s see the current state of our project tree:
myproject |_ src |_ MyAwesomeFeature.fs |_ App.fs |_ App.fsproj |_ Shared |_ Authentication.fs
This can be expressed in the project file as:
<ItemGroup> <Compile Include="../Shared/Authentication.fs" /> <Compile Include="MyAwesomeFeature.fs" /> <Compile Include="App.fs" /> <ItemGroup>
An important thing to note is Fable will translate F# source files to ES2015 modules using JS
import. This means that files which are not referenced by any other will be ignored (except the last file) including side effects. This is different behavior from .NET, where all files are compiled and executed, regardless of their relationship with the rest of the project.