Skip to content

Commit

Permalink
some more typo fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Jand42 authored Dec 23, 2022
1 parent 3906531 commit a40687d
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions user/jankoa/20221223-compile-to-javascript-dynamically.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ abstract: ""
identity: "-1,-1"
---

There are two big community projects existing for transpiling F# code to JavaScript: WebSharper and Fable. Hovewer, the focus of the two project is somewhat different, here is how I see it:
There are two big community projects existing for transpiling F# code to JavaScript: WebSharper and Fable. Hovewer, the focus of the two projects are somewhat different, here is how I see it:

* WebSharper has bigger focus on living inside .NET ecosystem, while Fable has bigger focus of integrating output into JavaScript ecosystem as well as other target languages.
* WebSharper supports C#, and with it correct semantics for all object-oriented .NET features of F# like inheriting from multiple base constructors, lazily executing static constructors. Code interop between C# and F# works as in .NET. Array operations do bound checks, F# option values are not erased, so you have maximum semantic compatibility with .NET and it's your choice to optimize with `JavaScript.Array` or `Optional` (erased option) types when needed for interop. Also, you can have server and client code living inside same project, encapsulating whole server-client functionality and JavaScript dependencies that can be distributed via NuGet.
* Fable has bigger focus on code output interoperability, while sacrificing some .NET and F# object-oriented features and semantics. It uses F#'s parser and type system to analyze F# source code that are intended for Fable translation only, or using compiler directives to diverge between Fable and .NET code. It distributes source code files via NuGet, not compiled dlls, and can depend on npm packages.
* WebSharper has bigger focus on living inside .NET ecosystem, while Fable has bigger focus of integrating output into the JavaScript ecosystem as well as other target languages.
* WebSharper supports C#, and with it correct semantics for all object-oriented .NET features of F# like inheriting from multiple base constructors, lazily executing static constructors. Code interop between C# and F# works as in .NET. Array operations do bound checks, F# option values are not erased, so you have maximum semantic compatibility with .NET and it's your explicit choice to optimize with `JavaScript.Array` or `Optional` (erased option) types when needed for interop. Also, you can have server and client code living inside same project, encapsulating whole server-client functionality and JavaScript dependencies that can be distributed via NuGet.
* Fable has bigger focus on code output interoperability, while sacrificing some .NET and F# object-oriented features and semantics. It uses F#'s parser and type system to analyze F# source code that are intended for Fable translation only, or using compiler directives to diverge between Fable and .NET code. It distributes source code files via NuGet, not compiled dll-s, and can depend on npm packages.
* WebSharper has tightly integrated metaprogramming features.
* You can write macros and code generators within your libraries by inheriting from `WebSharper.Core.Macro` and `Generator` types. Macros allow custom translation logic for annotated methods/types, while generators can create JS code output from some logic executing in compile-time that returns a JS string, F# quotation or WebSharper AST. For example macros allow for auto-implemented [two-way lensing](https://intellifactory.com/user/denuziere/20180228-clear-and-simple-reactive-code-with-websharper-ui-s-v) in `WebSharper.UI`.

WebSharper's main shortfall is that its output can be pretty crude and does not integrate with module systems and bundlers well enough. The original intention was that your main web project is a .NET project that can handle everything for you, this legacy got carried along and there was always more focus on improvements on the input side (C# support, more language and framework features, etc.) than on the output side. [WebSharper 7](https://github.com/dotnet-websharper/core/pull/1302) is under development now that will bring output up to modern JavaScript standards with module output, JS classes, get/set properties, arrow functions and more.

## How to use compiler dynamically
## How to use the compiler dynamically

While this update is under way, let us look at a minimal version of [Try WebSharper](https://try.websharper.com/), a simple web project that exposes JS translations of either F# or C# source code input on a minimal UI. This will eventually be a good tool to demo WebSharper 7's improved output.

Expand All @@ -32,7 +32,7 @@ dotnet run
The project uses both the `WebSharper.Compiler.FSharp` and `WebSharper.Compiler.CSharp` packages, which are containing the WebSharper compiler libraries as references to be used by our code, not as tools (which are used for translating WebSharper-enabled projects but not invoking the compiler).
These depend on `FSharp.Compiler.Services` and `Microsoft.CodeAnalysis.CSharp` (Roslyn) respectively, so we don't need to directly reference these.

WebSharper uses metadata embedded in dlls to guide its translation to conform to already translated projects with embedded JS files in them. Some of this metadata is used for the server-side runtime of web projects to enable client-server features of websharper for example creating controls on the server which will be filled in on the client with content (the `client` helper functions in `Site.fs`). Usually this runtime metadata does not need to contain any code expressions, just the overall shape of the generated JS so that event handlers and client-side placeholders can refer to it. But for on-the-fly translation, we also need the inline expressions from metadata, which are expanded upon use. This can be made accessible with a single new option in `wsconfig.json`: `"runtimeMetadata": "inlines"`.
WebSharper uses metadata embedded in dll-s to guide its translation to conform to already translated projects with embedded JS files in them. Some of this metadata is used for the server-side runtime of web projects to enable client-server features of websharper for example creating controls on the server which will be filled in on the client with content (the `client` helper functions in `Site.fs`). Usually this runtime metadata does not need to contain any code expressions, just the overall shape of the generated JS so that event handlers and client-side placeholders can refer to it. But for on-the-fly translation, we also need the inline expressions from metadata, which are expanded upon use. This can be made accessible with a single new option in `wsconfig.json`: `"runtimeMetadata": "inlines"`.

Now the server-side translation of both F# and C# are pretty similar in this sample:

Expand Down

0 comments on commit a40687d

Please sign in to comment.