Monday, February 13, 2023

The State of JavaScript and Modern Web Client Development

Here is a link to a white paper I wrote named, 'The State of JavaScript and Modern Web Client Development.' If you need help navigating the waters at a high-level in the modern web landscape, make sure to check out the article.

Monday, November 7, 2022

Overloaded Methods in TypeScript

If you've ever worked with a language like C# or Java you're probably often using overloaded method signatures to provide callers with an opportunity to have a similar outcome by passing a different number or type of parameters. However in TypeScript which is just a superset of JavaScript and adhering to all things JS under the covers, method overloading doesn't work the same with identical method names and parameter signature because there are no types to differentiate between. If you have (2) identical methods in JS being called the latter defined method on the prototype will be called, and the former ignored.


TypeScript has the benefit of type definitions at build time so method overloading is possible... kind of. If the goal is to have intellisense to see multiple definitions of the same overloaded method, we can certainly achieve that. If the goal is to have multiple definitions of the same method name with different parameter signatures and separate, different implementations, this out of the box is not possible and won't be like traditionally static typed, structured languages like C#. Regardless let's see how overloading does work in the vanilla form (I'll hint at conditional types at the end) using TypeScript and you can decide if you can leverage for your benefit.

The recipe for overloaded methods in TypeScript is that you can create 1...n method signatures, but only have a single implemented method representing any of the possible call combinations. Let's look at a code sample:

Above we have the overloaded method named start, that represents the potential to provide the different procedures to start an engine, based on the various engine types. Note the (5) overloaded method signatures, but only a single implemented method. The reason for this is the overloaded behavior and differentiation of methods is a design/build time only feature available due to the fact we are using TypeScript. In fact if you look at the transpiled JavaScript the only method shown is the single implemented method:

If you do try and use implementations on more than 1 method with the same name, TypeScript will warn you with a, "Duplicate function implementation" warning.

Looping back to our original goal using the properly implemented code, as the method caller if we want to see at design time a list of the various signatures, we have indeed accomplished that goal as you may scroll through and see the multiple, overloaded definitions:

However this comes at a bit of a sloppy cost for that single implemented method. In order to make this work the method signature must encapsulate all potential values that could be sent to satisfy the TypeScript compiler. This usually equates to using a Union type in the method signature to account for all possible types. The next hurdle is because overloaded methods are really a façade, you must manually pick apart what's sent and reverse engineer what you received at runtime. This usually equates to type guards, if statement, switch statements, or some combination to sniff out what you received, so you can proceed forward. All of this logic is that code above within our implemented method to determine what exactly we received.

It's even trickier to determine what's sent if you have (2) identical method signatures that are only differentiated by variable name like our 1st two methods below. This is not advisable even though it does work:

The long and the short of method overloading in TypeScript is that it is possible, but with a few caveats that may not make it sensible. I think if you only have (2) different method signatures, that are easily discernable at runtime in the implemented code, then this might make sense. However as the signature list expands, the logic to differentiate the potential values sent can get unwieldly. 

Lastly another potential option may be to use conditional types in the method signatures which rely on generics to sort out the types based on what the caller is sending. This could reduce the need for the implemented method to contain all the logic to sort out which values it was sent as it will be know already. However in this post I wanted to strictly do a 1:1 look at the concept of overloading as it may be known from other languages, and how it can be accomplished in TypeScript.

Wednesday, October 26, 2022

How to View Deployed Files for a Web App Using the Azure Portal

When debugging a web app and tracking down problems, especially newly created and deployed apps that aren't working, sometimes all that's needed is to look and see what's deployed to help determine the issue. This is trivial to do using the App Service Editor available from the Azure Portal.

Once logged into the portal, navigate to the website or specific deployment slot of the app where you'd like to browse the files. Viewing the menu of options on the left-hand side, select App Service Editor:

This will redirect to a location in a new browser tab which will show the folder structure and physical files present. Within the utility there are other useful functions available along the left-hand side in addition to the logging output to help diagnose and have insight into your deployed site.

This feature is still in 'Preview' mode so expect some changes over time to the utility, possibly being renamed, and on occasion being down. As noted you can always FTP into the directory as well as a secondary option.



Wednesday, October 19, 2022

Generate YAML from an Existing Azure DevOps Pipeline

Here's a quick tip if needing to generate a .yml file for CI/CD configuration from an existing Azure DevOps pipeline. There are several ways to build the .yml configuration file:

  • Make one from scratch
  • Use a template from GitHub or another similar project
  • Use the AzureDevOps pipeline editor and assistant
  • Use an auto-generated one created from a cloud portal (i.e. Azure portal)
However if the above solutions or any other aren't providing to be fruitful to your deployment configuration, you can leverage the classic editor from ADO to create a pipeline configuration visually via steps. This is often a means to an end to get working syntax in a methodical manner via form input, rather than through raw configuration.



Once you have a working pipeline however, it's ideal to get this configuration into your GitHub repository. This allows source control tracking on the configuration which is preferred to a pipeline used in a vacuum. If you used the classic editor to build a working pipeline, generating a .yml configuration is trivial. 

In ADO, navigate to the pipeline and find the ellipse next to, 'Run Pipeline.' From this menu you'll see an option to, 'Export to YAML.'


This will generate a .yml configuration file based on your working pipeline.


At this point you could add the .yml file to source control and create a new Azure pipeline connecting to your source control provider that leverages the newly created file.

Note different deployment systems use different YAML syntax or 'actions' so this may not be directly portable to another workflow for deployment. For example the .github/workflows directory in GitHub can connect to the repo from the Azure Portal in the Deployment configuration and use a .yml file. However the syntax is different for GitHub Actions, so the .yml file downloaded would only be a guide and require further massaging.



Tuesday, October 18, 2022

How to Activate an Azure Monthly Credit With Another Account When Subscription Login Denies Benefit

Scenario: You've been assigned Visual Studio Subscription (AKA MSDN subscription back in the day) by your organization, and would like to activate your free $150 (or similar) credit. Upon attempting the credit you get an error along the lines of, "You're not eligible with this benefit. Your organization does not allow activating this benefit." However you know the Azure credit is a benefit as it's listed as such on your subscription. Why an organization would block this benefit, I'm not sure nor how to inquire about resolving, but there's a simple solution.

Context: You switch companies, switch emails, a subscription expires, another is activated. This inconsistency creates havoc for your personal development and OSS work as all of your Azure resources have to be recreated over and over for new subscriptions (Note: moving resources is typically not an option as you can only do this across the same underlying subscription; see: Move Azure Resources). Now you've gone to login to your new subscription to use the Azure credit, and the benefit isn't allowed to be activated. Ideally you have a single, static, non-changing account login that you can associate varying subscriptions with over the years. The recommendation IMO is to use your personal GitHub login to associate Azure credits for 1...n Visual Studio Subscriptions. 

Solution: You can add an 'Alternate Account' to your Visual Studio subscription, that can be assigned the credit instead to associate with your current subscription. 

Breakdown:
  1. Log into your active and current Visual Studio subscription. Under the 'Benefits' tab there will be a box to active your Azure monthly credit:


  2. Upon selecting 'Activate' you'll be presented with a Microsoft login to proceed to the Azure Portal. If you select logging in with your organization's login which is the same as your Visual Studio subscription login, you get an error that the benefit is not allowed to be used for this ID: 


  3. Back in Visual Studio subscriptions, head over to the 'Subscriptions' tab:


  4. Add an alternate email that you'd like to associate with your Azure credit. Essentially this allows using that credit, with another valid Microsoft or SSO login. My suggestion is to associate the email with your personal GitHub login. This will help set you up in the future to be able to re-associate new subscriptions with the same login to ease transition. Note - whichever account you choose, this whole process will be much easier if it's already established as a Microsoft account and have previously logged into the Azure portal (https://portal.azure.com/). 


  5. After adding the alternate email, go back to the 'Benefits' tab and press 'Activate' for the Azure credit again (Step #1). This time when presented with the login, use the alternate email credentials. For a GitHub login, select 'Sign on options' and SSO authenticate with GitHub. If you used another Microsoft login as the alternate account, use those credentials.


  6. If you get a login error regarding STS or federation error (i.e. AADSTS900043 or similar), just close the browser tab and reopen portal.azure.com. This seems to be a 1-off issue with the handshake and has nothing to do with this overall process.


  7. Once successfully logged in your Azure monthly credit will be applied to the alternate email ID login you configured. To check the status, you can view your subscription(s) from the 'Settings.' 


One final note - once this process is done and as expected, if you try and activate again with another login (i.e. your organization's login, another email, etc.), you'll be presented with the message that this benefit is already used and can't be activated again. I'm not sure on how to re-link the monthly credit, so ensure the login you setup is the one you want to use.



Friday, December 4, 2020

The Absence of Pattern Thinking for Web Client Code

With 20 years of experience as a software engineer moving through the stack and using a lot of different languages throughout the years, I've seen a lot of good and conversely poor development implementations. I've also had the privilege of being able to work with languages (like C#) that placed a heavy emphasis as a community in  enterprise development around the mindset of using patterns and practices to make code more readable, reusable, and easier to communicate redundant and repeatable ways of creating applications and services. This has helped me immensely and provided me with a mindset on how to think and truly engineer a well built solution.

The priority of pattern thinking is missing

The problem I've seen over the last 5-10 years as a primarily focused JavaScript web client developer is the absence of this type of thinking. So much of the code I see written is just jammed into a file as a means to an end to complete a needed goal. I think unfortunately the explosion in JavaScript development and rapidly created JS developers due to demand has been partly to blame. I also think there has been so much focus on, "which framework/library," that has had a byproduct of having to learn so much just to get code implemented, that pattern thinking is just not at the forefront. Plain and simple there hasn't been time to organize thoughts or thinking around a sound architectural implementation using known patterns when the web client developer is just trying to get their head above water learning the framework, array of JS libraries, state management, CSS, responsive design, offline capabilities, mobile-like features, new work, enhancements, etc.. This in contrast to more stable back end languages that have had similar implementations going on for decades (albeit with new ways to wrap code or deploy; i.e. cloud) where the tenured experience has helped provide an environment where pattern thinking is much more prominent. I know this to be true, because I've been on that side of the fence as well.

Has it always been this way?

This isn't to say there has never been a focus on pattern for front-end code. Industry leaders such as John Papa were advocating for the module and reveling module patterns with ES5 code years ago, and even today alongside Dan Wahlin to carry the flag for architecting Angular apps and having a mindset for patterns and practices. Therefore a voice does exist from advocates for sound and well written code, but overall I just don't see the concrete evidence as much as I did when working with server-side code in C#/.NET. 

It's time we as a web client community when building enterprise web application push harder to use some forethought into how we implement our code borrowing concepts from known patterns and practices. It's not enough just to cram thousands of lines of code into a monolithic style .js/.ts file. This as an aside is one reason I'm not a huge fan of CSS in JS because it adds to desegregation of code and cramming everything into a single file. I don't consider myself old school to like separation of concerns (SoC), as it's really about organization of thought and practice. Much like the UI web component code we like to implement today with a mindset around segregating code into smaller, cohesive pieces of functionality, we must too apply that same style of thinking to the imperative code we write in JavaScript/TypeScript.

A high-level use case

Let me cherry pick a scenario I see more often than not in Angular. At a high-level speaking broadly, most modern Angular code has a thin service code file that makes an API call, and immediately returns an Observable with the result. The real result is that data is consumed and subscribed to in the component, and all presentation logic, data massaging, and appropriate (or sometimes inappropriate because it's IP) business logic is all done in said component. The result? A massive multi-thousand line big-ball-of-mud that's out of control and really difficult to maintain. It didn't start that way, right? The original MVP implementation was just a simple return and binding of data. However like any software that evolves, so does the need for more code and the initial pattern set forth, is scaled good or bad. In this case bad, and the component is out of control.

What if though something like the Command Pattern (or ideas from it) had be used from the inception? The component only acts as an air-traffic controller of sorts; it doesn't really know how to do anything except direct the traffic. It assembles all needed information, builds up and executes the command on the service where the real work happens (in 1..n services). This pattern also lends itself to creating immutable models in the component and they are only ever changed in the service. The service streams the data from an Observable, and all the component does (with minor exceptions) is bind to the new data. This is a much cleaner approach and a highly repeatable pattern for any experience level. Even if this particular approach seems heavy as you're building a smaller application, knowing patterns and their purpose for use will still lend your design ideas about how to better implement and organize your code. 

In contrast to OO patterns and practices but still with critical and planned thinking at the forefront, we could also use a functional programming paradigm (and patterns specific to FP), and leverage things like pure functions to avoid side effects with a goal of consistency and having more readable and logical implementation. Any of these options are better than the absence of any plan, which results in a poor implementation that's prone to bugs and being difficult to maintain.

In the end we didn't complicate the code, we just implemented it differently for the major gain or readability, reusability, and testability. I liken it to these images I used over 10 years ago when talking about patterns and practices in C#. Both containers below have the same content, but which one would you rather grab to get what you need? The answer is simple; the one that is organized.


The plan forward

The question is how do we learn about these patterns and when to apply them in our code? Well the answer is a combination of getting educated on well known patterns and gaining experience using them. It is however an art, and there is a balance to be had on how to use them most effectively. The cynics hear 'patterns' and sometimes get scared off saying, "that will overcomplicate the code!" There are times I agree. How can I spot the difference? Experience. If you don't have any, learn from others. One of my favorite words in the industry is 'pragmatic.' The ability to know balance in code and when and how to use powerful patterns to aid not hinder code. If the two ends of the spectrum are anarchy and over-architecture we want to be somewhere close to the middle. The problem is in my experience, we're too often close to the anarchy-style of implementation on the web client. I think the crazy saving grace that we back into is that since web client frameworks and libraries have only a 2-4 year tenure on average before some major overhaul, all this bad code is made obsolete before it really begins to stink things up. However during that time period it would behoove us to write code that is implemented with better patterns and practices to help extend the life and make the journey a whole lot easier.




Friday, December 20, 2019

How to Prevent Visual Studio from Compiling TypeScript

If you are building a Single Page Application / JavaScript Web application using Visual Studio, you've probably already run into the overlap between tooling that surrounds npm and the tooling within Visual Studio. As web development moves further away from the bells and whistles needed from the IDE (unlike heavy server-side web technologies like ASP.NET MVC that are heavily dependent upon the IDE), separating a project from these 'features' can be not quite straight forward. While the practice of using Visual Studio for modern web development isn't as prevalent these days with much of the coding taking place in streamlined IDEs like Visual Studio Code, there are still a lot of projects that exist and have a hard time decoupling from Visual Studio, MSBuild, and ASP.NET because of their coupled nature. This process will help in this interim stage while the code is still fully integrated and run from Visual Studio.


One of these tasks is preventing Visual Studio from being responsible for building TypeScript and allowing your tooling (i.e. Webpack, Gulp, Grunt) to be in charge instead. The idea here is that your tooling has been configured to lint, minify, build, concat, bundle, copy, whatever all of your project files exactly as you desire. At this point you don't really need MSBuild involved in transpiling your JavaScript to TypeScript as it would be redundant and often times problematic. To prevent Visual Studio from doing any compilation of TypeScript preform the following steps:

1. Ensure a tsconfig file is added to the project and configured correctly

TypeScript and any build process you are using will work together based on the configuration in tsconfig.json. This file can be hand-rolled from scratch, or may have been generated for your project from a process like ng new and the Angular CLI. You can also generate a default tsconfig file (recommended approach as opposed to creating from scratch) using the following command:

tsc --init

This will generate a default configuration file for TypeScript compilation. Your web-client's code build process will need to point to this file and using it as a driver for the TypeScript compilation behavior.

2. Modify the .csproj project file to prevent TypeScript from compiling

Within Visual Studio, right-click your project and select the option to edit the .csproj file. These options are in a XML format and the following needs to be added:

<PropertyGroup>
   <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
</PropertyGroup>

If you still want MSBuild to handle your TypeScript compilation there are several options that will change the behavior: 


One of the only primary use cases I can think allowing MSBuild to handle TypeScript compilation is for using TypeScript independently of a framework/app like Angular or React when using standalone in an ASP.NET MVC application. Otherwise the native build processes of your front-end stack are much better off being used to build TypeScript as opposed to MSBuild.