bit-badger / Giraffe.Htmx

Extensions for Giraffe to support development with htmx

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Runtime Error] System.IO.FileNotFoundException: Could not load file or assembly 'FSharp.Core, Version=8.0.0.0

SIRHAMY opened this issue · comments

Hey all, love the package but can't seem to get it to work.

Context

  • Running: dotnet 7

Using in simple page:

        div [] [
            (
                if props.Page < 1
                then emptyText
                else 
                    button [
                        _hxGet $"/sentinels?page={props.Page - 1}"
                        _hxTarget $"#{sentinelTableId}"
                        _hxPushUrl "true"
                    ] [
                        str "Previous"
                    ]
            );
            (
                if not props.HasNext
                then emptyText
                else 
                    button [
                        _hxGet $"/sentinels?page={props.Page + 1}"
                        _hxTarget $"#{sentinelTableId}"
                        _hxPushUrl "true"
                    ] [
                        str "Next"
                    ]
            )
        ]

Problem

So my app builds fine but when I try to actually use one of these Giraffe.ViewEngine.Htmx imports it fails at runtime with this error:

fail: Microsoft.AspNetCore.Server.Kestrel[13]
2023-12_fsharp-htmx-giraffe-view                                                          |       Connection id "0HMVLM56KO179", Request id "0HMVLM56KO179:00000001": An unhandled exception was thrown by the application.
2023-12_fsharp-htmx-giraffe-view                                                          |       System.IO.FileNotFoundException: Could not load file or assembly 'FSharp.Core, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.

I can reproduce this by trying to use any of these imports like this:

printfn "hamytodo: this is an _hxget %A" _hxGet

Hypothesis

I think I'm missing Fsharp.Core 8 so this may just be a me problem. But it seems odd that I can DL and use this package without any errors being thrown until runtime.

Also, I can't seem to update my Fsharp.Core to 8. I'm wondering if Fsharp 8 requires dotnet 8 so this package says it can run on dotnet 6 and 7 but actually requires 8?

idk.

Q1: Any ideas as to how this happened / ways to fix?

Q2: Any ways to prevent this from happening in the future?

Let me see if I can duplicate it. I thought the deps in the package would handle that if it's listed, or that NuGet would complain if it couldn't resolve it on its own. Thanks for reporting this!

There are a couple of things you can try:

  • In your .fsproj file, add <PacakgeReference Update="FSharp.Core" Version="8.0.100" />
  • Pin version 1.9.6 of this library; it was built against F# 7.

I'm investigating some conditional build dependencies, where I could reference a specific version of FSharp.Core based on the target framework. I'll leave this open and associate whatever the fix is here, so you'll know when it's ready.

p.s. Sorry for the delay on this - day job has been crazy!

Two paths here that I can see:

  • @danieljsummers is the multitargeting necessary for this library? Are you doing anything with the net7.0 and net8.0 targets at all in the codebase? If not, then you could go back down to a net6.0 target only and use <PackageReference Update="FSharp.Core" Version="6.0.0" /> in your .fsproj to pin the library to the .NET 6-compatible version of FSharp.Core. This lowest-compatible version specification is what library authors should do (since your lib isn't actually using FSharp.Core until runtime, you can let consuming Apps decide what version that want to bring, so long as it's at least FSharp.Core 6.0.0).

  • if you are doing something specific for .NET 7 and/or .NET 8, then you'll need to make your <PackageReference Update= items conditional on the TFM, but still at the earliest version of FSharp.Core for each TFM. That would look like this:

<ItemGroup>
  <PackageReference Update="FSharp.Core" Version="6.0.0" Condition="'$(TargetFramework)' == 'net6.0'" />
  <PackageReference Update="FSharp.Core" Version="7.0.0" Condition="'$(TargetFramework)' == 'net7.0'" />
  <PackageReference Update="FSharp.Core" Version="8.0.0" Condition="'$(TargetFramework)' == 'net8.0'" />
</ItemGroup>

Note that I really don't suggest this unless you're using some functionality introduced in .NET7/.NET8 in this library for each of those TFMs (i.e. new BCL APIs, new F# syntax like the F# 8 improved interpolation syntax, etc).