Thursday, November 02, 2023

F# and OpenSilver v2.0

An update to the previous series of posts following the v2.0 stable release of OpenSilver.

The good news is that proper F# support in promised in the pipeline, but for now we still have to do some work.

Proceed as before, but in the F# project that inherits from the abstract C# w/XAML, a NuGet based reference to OpenSilver 2.x invokes the XAML preprocessor, and adds a file in the intermediate output directory to the compilation list. I've not found any simpler way to suppress this than by side-stepping NuGet entirely for this project

    <Reference Include="OpenSilver">
      <HintPath>$(NuGetPackageRoot)opensilver\2.0.1\lib\netstandard2.0\OpenSilver.dll</HintPath>
    </Reference>

and having to manage the version.

The other thing I noticed in 2.0 was that the sense of the Y-axis seems to have changed wrt render transforms, e.g. to draw a clock face with a series of lines radiating from a centre of (120,120) like this, rotations incrementing 30 degrees at a time, the negative Y values from 1.1 needed to be positive

        <Line
      Name="t1"
      X1="0" Y1="-108"
      X2="0" Y2="-100"
      Stroke="White"
      StrokeThickness="2">
          <Line.RenderTransform>
            <CompositeTransform Rotation="30" TranslateX="120" TranslateY="120" />
          </Line.RenderTransform>
        </Line>

and for the clock hands, add an extra 180 degrees as well as negating the Y values (that the unlabelled 1 o'clock and 7 o'clock lines have swapped makes no odds, but the hands are important).

The resulting code for running with v2.0 can be found here. The published code comes to ~130Mb, which is a lot chunkier than 25kb of JavaScript needed to do the job, but I guess it could be possible for many apps to share the same library files.

2 comments :

Яков said...

Hi Steve!

Firstly, thank you very much for the using OpenSilver and providing the fantastic example of integration with F#. It is wonderful!

Regarding the issue with the XAML preprocessor, you're correct about the failure due to its inability to generate F# code. To resolve this, you can bypass the preprocessor by adding the following line to your csproj file:
true

As for the auto-generated file being placed in the project's root folder, that's quite unusual. A potential workaround could be to manually relocate this file to the intended 'obj' directory.

After implementing these adjustments, the build process should proceed smoothly.

After these two steps, the build should work!

I tried to publish your example. I can not get 130 mb! It is much smaller.
Also, I have added these two properties to make it even smaller:
false
en-US;en

The first one prevents generating .br and .gz for all assets. And the second one disables multiple localizations for Satellite assemblies.
As a result, I got 30 mb :) It is still noticeable, of course, and we will investigate how to make it smaller.

Also, I have attempted to publish AOT version. It is 80 mb :)

Your testing and insights are invaluable, and your blog post is a significant contribution to our community. Thank you once again for your support and for sharing your findings.

Steve Gilham said...

Some cross-purposes here

* the .XamlDesigner.fs reference is to the intermediate output (.obj) directory; I had not spotted the file itself being created in $(ProjectDir), there being no XAML in the project, amongst other things
* The '<' and '>' delimited text in e.g. 'true' have been stripped in the comment engine as invalid HTML, but I think I have managed to reverse engineer what they were
* Yes, I was building AOT, and just reporting the size of the entire publish folder.