Skip to content

Instantly share code, notes, and snippets.

@nojaf nojaf/blog.md Secret
Last active Mar 25, 2019

Embed
What would you like to do?
Fable 2.2 Axxes blog

Introduction

With the release of Fable 2.2 it is now (back) possible to compile .fsx files. There are some subtle differences in this approach and in this blog post, I'd like to illustrate how your workflow could be.

Initial setup

Using a script file is actually not all that different from the regular Fable approach (see minimal sample). When using webpack, point your entry to your script file and make sure that the fable-loader is matching .fsx as well.

...
module: {
        rules: [
            {
                test: /\.fs(x|proj)?$/,
                use: {
                    loader: "fable-loader"
                }
            }
        ]
    }
...

If for example, the content of the script file is merely to print something like

printfn "Works!

Fable already can compile this to the expected console.log statement.

Using dependencies

Of course logging to the console bearly proves anything. How can we import some dependencies and do something useful?

This is where Paket can really shine. Next to being a great alternative to NuGet, it can also generate a script file that contains references (#r) to all the listed dependencies.

Step by step

Paket can be installed as a dotnet cli tool.

dotnet tool install --tool-path .paket Paket --add-source https://api.nuget.org/v3/index.json --framework netcoreapp2.1

Moving forward execute .paket/paket.exe init to generate an empty paket.dependencies. There we can list whatever packages we need.

F.ex.

storage: none
source https://www.nuget.org/api/v2
framework: netstandard2.0

nuget Fable.Browser.Dom 1.0.0-alpha-004 alpha
nuget Fable.React 5.0.0-alpha-005 alpha

After .paket/paket.exe install, we can generate a load script via .paket/paket.exe generate-load-scripts -f netstandard2.0 -t fsx. This creates the following script file:

namespace PaketLoadScripts

#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.core\\2.1.0-alpha-002\\lib\\netstandard2.0\\Fable.Core.dll" 
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.browser.blob\\1.0.0-alpha-001\\lib\\netstandard2.0\\Browser.Blob.dll" 
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.browser.event\\1.0.0-alpha-001\\lib\\netstandard2.0\\Browser.Event.dll" 
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.browser.webstorage\\1.0.0-alpha-001\\lib\\netstandard2.0\\Browser.WebStorage.dll" 
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.browser.dom\\1.0.0-alpha-004\\lib\\netstandard2.0\\Browser.Dom.dll" 
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.react\\5.0.0-alpha-005\\lib\\netstandard2.0\\Fable.React.dll" 

Note that storage:none, will references everything from my global NuGet cache.

Loading the generated script

With a simple #load directive we can import the generated script. #load "../.paket/load/netstandard2.0/main.group.fsx". And from now on we can use our dependencies.

Extra

Depending on what editor you are using, you might want to add

#if INTERACTIVE
#r "netstandard"
#endif

below the #load, as netstandard and fsi will only be fully supported in .NETCore 3.0.

Motivation

So when does this approach make sense?

  • If you are already using Paket.
  • When you only have a single file and you feel like a fsproj file is a bit of an overkill.
  • Or when you want to start out small and switch to a fsproj when the need arises.

Sample

Check out https://github.com/nojaf/fable-fsx-sample for a larger sample.

Final words

I hope you enjoyed this blog post and it all makes sense. If you have any suggestions or questions please leave a comment.

Yours truly, Florian

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.