Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about compile time file ordering of dependent fable nuget packages #3833

Open
ThisFunctionalTom opened this issue Jun 7, 2024 · 8 comments

Comments

@ThisFunctionalTom
Copy link
Contributor

Description

I have a fable compatible nuget packages Constants and Library where Library depends on Constants.
When I add package reference to Library in our SPA app and compile it with fable I get F# compiler error while compiling sources of Library that the namespace of Constants is not known.

I executed fable compiler with --verbose flag and have seen that the source files of Library come before the source files of Constants. Both of the package sources can be found in fable_modules so I guess the dependencies resolved correctly.

Can I somehow influence the compile time ordering of files from fable_modules? Am I doing something wrong? How does the Fable order the files from referenced fable nuget packages?

Expected and actual results

I would expect the fable compiler to respect the nuget package dependencies order and sort the files when compiling accordingly. In my case first all the files from Constants should be compiled before the files of Library and at the and the files from the SPA app.

Related information

  • Fable version: 4.18.0
  • Operating system: windows 11
@ThisFunctionalTom
Copy link
Contributor Author

I just found that there is a project_cracked.json file. In this file the files are in the correct order but in the --verbose log the files are in different order.

@MangelMaxime
Copy link
Member

Hello @ThisFunctionalTom,

Are you trying to consume the packages via NuGet or using ProjectReference.

If this is the former, you need to make sure to release a Fable compatible package. The main things being you need to include the F# source files in a fable folder.

In order to do so, you can use the all new shiny Fable.Package.SDK which automate a lot of things for you and guide you.

Or you can do it the manual way by using Fable documentation (in the future it will be updated to use Fable.Package.SDK as it more friendly to use).

@ThisFunctionalTom
Copy link
Contributor Author

Hi Maxime,

Yes both nuget packages Constants and Library are fable compatible with sources in fable folder. I also find this sources in fable_modules of the SPA app. As I said, I guess it is the order of the files on the command line of F# compiler that is wrong. Here the files of the Constants come after the files of the Library and F# compiler fails because in Library we use Constants.

What's strange is that in the project_cracked.json file the order of the files is correct.

Maybe if you could navigate me where the F# compiler is called in Fable I could maybe find the error myself or maybe find what am I doing wrong.

I could try to reproduce it with some small projects but I am not sure if it will happen again. I would first like to find out how the files on the command line of F# compiler are sorted.

@MangelMaxime
Copy link
Member

Could try compiling using --test:MSBuildCracker flag ? This is using MSBuild to resolve the dependencies instead of Buildanlyzer.

Resolution of the project is done by https://github.com/fable-compiler/Fable/blob/main/src/Fable.Cli/BuildalyzerCrackerResolver.fs

Or the new when the flag --test:MSBuildCracker is set https://github.com/fable-compiler/Fable/blob/main/src/Fable.Compiler/MSBuildCrackerResolver.fs

The full projects options should be build here: https://github.com/fable-compiler/Fable/blob/1a1854acfff1cc72dabdda3e946d007e93948755/src/Fable.Compiler/ProjectCracker.fs#L809C5-L809C23

@ncave
Copy link
Collaborator

ncave commented Jun 8, 2024

Perhaps a repro can help figure out what's happening.

Here the the source file logic for Fable-compatible nuget packages. But that doesn't use MSBuild, just parses project XML, so that might explain the difference in package order in project_cracked.json.

My guess is that the dependency order provided by MSBuild might be different than what you expect from just looking at the project.
As @MangelMaxime suggested, try using --test:MSBuildCracker to see if that changes anything.

Also, is the package dependency order that you get when compiling with .NET F# (using --verbose) same, or different?

@ThisFunctionalTom
Copy link
Contributor Author

I just debuged the Fable Compiler while compiling our SPA app and I think I found the problem.

I think the problem is in sortFablePackages function because it compares package dependencies case sensitive and does not sort dependencies if the casing is different in fsproj file and in nuspec files of fable packages.

match List.tryFindIndexBack (fun (x: FablePackage) -> 
    pkg.Dependencies.Contains(x.Id)) acc with
...

Instead it should probably be

match List.tryFindIndexBack (fun (x: FablePackage) -> 
    pkg.Dependencies |> Set.exists (fun dep -> dep.ToLowerInvariant() = x.Id.ToLowerInvariant())) acc with

I will try to make a pull request if it is OK.

@MangelMaxime
Copy link
Member

I think it makes sense, because in the fsproj we can use Fable.Core or fable.core for the name of the dependency and it resolve to the same package. At least, it doesn't seems to break.

@ThisFunctionalTom
Copy link
Contributor Author

I think I fixed it. The pull request link is above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants