Wednesday, January 30, 2019

I'm excited about WebAssembly, but not as much about my beloved .NET, Blazor's implementation

As a web client developer these days, I'm sold on WebAssembly and looking forward to it's adoption by the multiple languages that can compile to it. However interestingly one of the things I'm beginning to feel is my personal dislike for the Blazor syntax and implementation. I suppose my multiple years being entrenched in JS/TS with really enjoying TypeScript + the SPA frameworks that have a relatively clean separation of markup (declarative) and logic (imperative) has made me have a bit of dislike for lacing the view directly with imperative view logic like this in Blazor:

@page "/myorders"
@inject HttpClient HttpClient

<div class="main">
</div>

@if (ordersWithStatus == null)
{
  <text>Loading...</text>
}
else if (ordersWithStatus.Count == 0)
{
  <h2>No orders placed</h2>
  <a class="btn btn-success" 
        href="https://www.blogger.com/2404">Order some pizza</a>
}
else
{
  <text>TODO: show orders</text>
}

As a side of humor, to format code blocks on this blog I have to select a 'brush' for the language formatting. Case in point, in the above snippet I wasn't sure if I should have picked HTML, C#, or Blazor.

This is probably because I was never a fan of the classic ASP, MVC Razor, or even Blazor implementations where view logic is interlaced with the markup (for web client code I'd even throw in JSX - as explained here). This doesn't matter a pile of beans really because this is all subjective and has absolutely no bearing on how successful Blazor or any other language targeting WebAssembly will be. I actually love the .NET stack and was carved from that block since the beginnings of my professional career, but I just don't like that particular style of implementation for the web. Shoot for all of ASP.NET's webforms shortcomings, the view overall was relatively clean (keeping logic in code separate from the markup) and pure aside the fact the tags may have been ASP.NET server-side controls but still took the shape of HTML tags (analogous in form to today's custom HTML elements).

I also do not like the JSInterop style in Blazor. You can invoke JavaScript functions from within C#, and that alone is handy I suppose, but messy. The functions you want to invoke must be available on the global scope of windowYuck. JavaScript scope and encapsulation was difficult enough to manage through the years, I'd rather not go back to the days of hanging code off the window object making everything globally available. In 100 level examples this seems fine, but get to 10's or 100's of thousands of lines of code in an enterprise app and this could get ugly.

<script>
  window.MyFunction = (someValue) => {
    //JS code here...
  };
</script>

using Microsoft.JSInterop;
public class JsInteropExample
{
  public static Task MethodName(strings someValue)
  {
    return JSRuntime.Current.InvokeAsync("MyFunction", someValue);
  }
}

I'm probably not alone in my opinions, and that's why I'll be keeping an eye on the ability to use TypeScript as a target for WA. I like JS/TS and am comfortable with it for developing web applications. I feel many client side developers may have a similar sentiment and not want to either learn a server-side language, or just prefer the front-end languages they've been using for years. TS on it's own won't be enough (it's just a language), so it would have to be TS + some web framework (??) and we'll have to wait for the pieces to come together.

To that end I'll keep an eye on things like assemblyscript which is a TypeScript to WebAssembly compiler. It doesn't appear to have the traction some of the other compilers do at the moment, but I'm sure it or something similar will gain momentum as WA picks up and the masses of web developers may not feel like using C#, C++, or Rust.

AssemblyScript: a TypeScript to WebAssembly compiler

AssemblyScript: Status and Roadmap

I'm not counting Blazor out for sure, and it's still going to evolve as it's only an experimental project at the moment. I really enjoy developing in C# so it seems like a great match, but in it's early stages it's rough around the edges and maybe that's just my opinion that's shaped as a front-end developer. I'm pragmatic and will not count out the usefulness of developing on a single-stack and this is where Blazor shines for .NET developers. 

I'd be interested in feedback or thoughts about using TypeScript to transpile to WebAssembly or anything else along these lines, so please feel free to leave a comment and let me know.

1 comment:

  1. Couple of points:

    Syntax: I get that you may not be a fan of it. One thing, things like putting everything in "functions", it's easy to do that for demo purposes, but I'd try to move to having things in a "model" rather than inlining the code in the page. Kind of akin to having logic in a code behind (though I get your example wasn't specific to that, just a point about Blazor syntax and functionality). You *can* do it, but overall it's something I think to avoid. I think as Blazor gets closer to RTW, practices will shake out in terms of what to do "right" and what isn't.

    JS interop: you raise a valid concern. My guess (purely a guess) is that the JS interop is there in part because WebAssembly has no native DOM access. The implementation right now may be "bleh", if you have a concern, I'd strongly recommend posting something on Blazor's issue page (and maybe there's one out there for this one). It's still a project in flux, so now's the time to provide that valuable feedback to the Blazor team directly - https://github.com/aspnet/Blazor

    I put very little right now into a TypeScript-to-WebAssembly version. AssemblyScript is a nice experiment and I'm impressed with what it does, but a "real" implementation needs solid backing, like something from MS, so....right now, I don't see this happening (but I'm open to being happily surprised on this).

    ReplyDelete