No error on second compile for project with missing transient dependencies.
I was working on the SAFE.Utils repository, and ran into some weird issue when compiling and running tests.
This is my package.json:
{
"type": "module",
"scripts": {
"pretest": "dotnet fable -o bld",
"test": "mocha bld"
},
"devDependencies": {
"mocha": "^10.8.2"
}
}
on NPM run test, the compiler failed on the initial run, because Fable.SimpleJson and Fable.Remoting.Client were missing dependencies:
Started Fable compilation...
Compiled 21/21: ..\..\src\Client\SAFE.fs
Fable compilation finished in 2329ms
.\bld\fable_modules\Fable.SimpleJson.3.24.0\SimpleJson.fs(6,12): (6,18) error FSHARP: The namespace 'Import' is not defined. (code 39)
.\bld\fable_modules\Fable.Remoting.Client.7.32.0\Extensions.fs(13,30): (13,40) error FSHARP: The type 'FileReader' is not defined. (code 39)
.\bld\fable_modules\Fable.Remoting.Client.7.32.0\Extensions.fs(37,10): (37,14) error FSHARP: The type 'File' is not defined. (code 39)
.\bld\fable_modules\Fable.Remoting.Client.7.32.0\Extensions.fs(82,32): (82,35) error FSHARP: The value, constructor, namespace or type 'Dom' is not defined. (code 39)
.\bld\fable_modules\Fable.Remoting.Client.7.32.0\Extensions.fs(87,9): (87,21) error FSHARP: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. (code 72)
.\bld\fable_modules\Fable.Remoting.Client.7.32.0\Extensions.fs(89,9): (89,22) error FSHARP: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. (code 72)
.\bld\fable_modules\Fable.Remoting.Client.7.32.0\Extensions.fs(91,17): (91,20) error FSHARP: The value, constructor, namespace or type 'Dom' is not defined. (code 39)
...
But on the second run, compilation was skipped, and tests ran:
Fable 4.23.0: F# to JavaScript compiler
Minimum @fable-org/fable-library-js version (when installed from npm): 1.6.0
Thanks to the contributor! @battermann
Stand with Ukraine! https://standwithukraine.com.ua/
Parsing SAFE.Client.Tests.fsproj...
Retrieving project options from cache, in case of issues run `dotnet fable clean` or try `--noCache` option.
Project and references (21 source files) parsed in 146ms
Skipped compilation because all generated files are up-to-date!
> test
> mocha bld
This behavior is quite confusing. Should fable generate a bundle, even if compilation fails?
I recreated the issue on a separate branch for a minimal reproduction.
Should fable generate a bundle, even if compilation fails?
Fable don't generate bundles, it generates 1 JS file per F# file.
But indeed, in theory Fable should invalidate the cache if the dependencies changed.
What do you mean by second compilation is it a full compilation by calling dotnet fable build twice ? Or is it using the watch mode?
Right, sorry for the incorrect word usage.
The dependencies do not change, and I think that's the odd thing: You can run the fable tool twice on the same input, with a different outcome:
- The first time it fails (which we expect, because we are missing a dependency)
- The second time fable does not compile, because the existing output is up to date, which also means that it also does not fail
The dependencies do not change
Sorry, what do you mean by that?
In the first, one you mentioned:
- Compile with a missing dependency -
dotnet fable - Install the missing dependency
- Compile again with
dotnet fable
Is that correct?
No, what I'm trying to say is that:
- I compile using
dotnet fable- this fails because of a missing dependency - Without changing anything, I compile again - this succeeds, because all generated files are up-to-date
I would expect number 2 to fail as well
I think I've had this type of thing happen during plugin development. Does this behaviour occur when you have tests fail? Or after trying to compile something that fable did not accept?
What I find is that these things happen when the project hasn't been restored, and the dependencies are not linked properly. Sometimes I find compiling with fable will break the links, and I'm not sure how this works; probably to do with the intermediate steps that fable takes to compile the program. If one of those steps is interrupted, or it doesn't restore properly during that process, then I won't be able to compile until I restore the project.
At this point though, most of my screen goes red on Rider, but sometimes not. It's almost always fixed by either reloading the project or restoring the project.
Sometimes I find compiling with fable will break the links, and I'm not sure how this works; probably to do with the intermediate steps that fable takes to compile the program.
By default Fable 4, was restoring the project as a csproj which could mess up the obj folder.
We workaround that by doing a force restore against the fsproj once the dependencies information were captured.
Which means like you hinted if the process is interrupted it could mess up something perhaps. To confirm, @Larocceau could try to use --test:MSBuildCracker flag to force using MSBuild directly.
With Fable 5 with moved away from this behavior by using MSBuild directly.