Karma

[Flight Assist Off] Part 1 – Angular Without the CLI

Series Intro

Welcome to my new blog series, Flight Assist Off. In this series, I hope to cover the challenges and benefits of running an Angular (2+) application without relying on the Angular-cli. For the uninitiated, Angular is a typescript-based web application framework from Google. This is distinct from AngularJS (itself a javascript based web application framework from Google) because of a complete rewrite and paradigm shift between versions 1.X and 2.X. We refer to the former as AngularJS, and the latter as just Angular (or Angular 2+, or Angular.io…). To ease the transition for AngularJS developers the Angular team created the Angular-cli, a command line utility for generating Angular projects and their constituent pieces. This tool grew in popularity to the point where later releases of Angular essentially REQUIRE the cli in order to work. The official documentation for Angular describes how to build and test the application ONLY via the CLI. It should be noted that the CLI is not actually essential for the framework, and it can be built and tested like any application framework project such as React. However, if you only read the official documentation, you could be forgiven for believing otherwise.

So Why Not Use the CLI?

Given that the CLI is built to be the easiest way to build an Angular application, and the documentation becomes practically worthless without it, why would anyone skip the CLI? I can only speak for myself, but I think I have a pretty good reason and good evidence I am not alone in my line of thinking. My personal reason is a desire to maintain control over my own projects. When you use the CLI to build your application, your build process is one step: ng build. If that step fails, you have zero visibility in to what went wrong. Behind the scenes, ng build is using webpack, a build tool/bundler which relies on loaders and plugins to handle various filetypes and situations. These loaders and plugins are often very dynamic, with plenty of configuration options to best fit your use case. However, in an ng build scenario, you have no freedom to alter those for your situation. This means that if your application doesn’t conform 100% to what the Angular-cli team expected, you are SOL. The same issues exist for testing. Generic unit tests are generated for new components and services, but the actual meat of the test runner is hidden from the dev. There are certain configuration values you can pass through the global angular.json CLI config file, but once those options are exhausted, you are stuck. The Angular-cli team were aware of these issues early on, and included a command called ng eject which output your webpack.config.js and karma.config.js files, and updated your build scripts to call them appropriately. Once Angular 6 rolled around though, CLI users were greeted with a message telling them that ng eject was deprecated, and no longer an option.

ng eject was "temporarily removed", permanently

Using the CLI, you protect yourself from having to learn a litany of new tools just to use Angular. Webpack and Karma configuration is handled for you, file structure on disk is dictated for you by the tool, and new components, routes, and services all start with the boilerplate handled for you. But once something doesn’t go exactly as expected by the CLI team, you are left with only one option: open an issue on the Angular github, and hope it will be addressed. When I build applications for a job, being completely blocked by a third-party is a worst-case scenario. Especially given that since this is the only venue for many people to correct their broken builds, there are LOTS of issues open at any given time. I want to remind the reader that I am an Angular fanboy, and have not fallen prey to the React hype, but let me drop some comparisons here. According to similartech.com, React has nearly twice as much usage across the web as Angular. However, Angular has nearly twice as many issues on their github. At the time of this writing, there are 2,511 open issues on the Angular repository (1 of them mine, open for over 2 years!!). React, on the other hand, has 562 issues, nearly a fifth of Angular’s count. Obviously issue count is not the most exact indicator here, but I can tell you from a casual perusal that the tone of Angular issues tend to be much more in the vein of desperation, because they have hit the limit of what they are allowed to change in their own application.

React has many more users, but far fewer github issues

Black Boxes

This obfuscation of vital parts of the build process behind simple commands is what is known as a “black box.” A black box can be roughly defined as anything which prevents the user from seeing the its inner workings, leaving the user to trust the output without necessarily understanding how it was produced. Black boxes are not inherently a bad thing either. The computer I am typing this post on is utilizing hundreds of black boxes to run this browser. Compilers, assemblers, and OS syscalls could be considered black boxes, since the average programmer can just rely on them to transform their high-level language in to a working program on a given system without understanding how they do so. These kinds of black boxes act as building blocks, allowing developers to build more and more complex applications by standing on the shoulders of giants.

The Angular-cli to me qualifies as a different black box entirely. It allows users to get right in to the act of developing their web application, but at the cost of failing to learn the skills that will be required for any other web application framework. When Angular inevitably falls out of style (as all frameworks eventually do) there will be a plethora of developers who have built successful applications in their career and have zero transferable skills to other systems. In the meantime, they are encouraged not to experiment with new tools, new folder structures, or complex use cases, because if they reach a point where the builds or tests fail, the docs will be of ZERO assistance. I am convinced that this problem is a large motivator of the recent swelling in React popularity.

Flight Assist Off

What if I told you there is a better way? There is a way to use all the fantastic tools the Angular team has built for us, leverage all the coolest new features of each release, and do so in a way which will allow you to do it again in the future with different tools! I’m not going to say its an easier way. The cost of opening the black boxes is that you now have to understand how those boxes worked well enough to recreate them and tweak them to your needs. You will be infinitely more in control of your application, but the safety net will be gone. You must sink or swim of your own merits. If that sounds like something you are interested in, please stay tuned for the rest of this series! I’ve created a repo on my github for use as a starting point which utilizes all the tips and tricks I am going to cover in this series. If you are the type to read ahead or who prefers working examples, please check it out here: https://github.com/swimmadude66/AngularPWASeed.

My goal of this series is two-fold. First, I’d like to raise awareness of this problem to the point that maybe the Angular team will consider adding documentation which does not rely solely on the CLI. The second is to record the methods I use as my own form of documentation. After I spent a solid week attempting to get Karma working with Angular with the limited resources available on Google (since the official docs are again, ZERO assistance), I spent ANOTHER week experimenting with the configurations until I understood what exactly was needed to make this work so that I could pass it on to you. I pray no one ever goes through that hell of reading a dozen articles titled “How to test Angular” that all boil down to “Write tests, run ng test.”

To those goals, I will be writing several more parts to this series in the coming weeks. My rough outline (subject to change) is as follows:

  1. Part 1 – Series Intro and Problem Statement
  2. Part 2 – How to Build an Angular App Without ng build
  3. Part 3 – Testing an Angular App Without ng test
  4. Part 4 – Cool Shit You Can Do Without Angular-cli
  5. Part 5 – How We Made Angular Fix Their Docs! (Hopefully)

I will update the parts above with finalized titles and links to the posts when they are ready. In the meantime, please leave a comment if I this is something you’d appreciate or even if you just want to tell me what I got wrong. Thanks for reading, and I hope to see you on the next posts!