Wednesday, January 30, 2019

Coming Up to Speed with Angular 6/7

Over the course of the past few months, I've been making a study of current JavaScript UI frameworks. Angular presently holds the lead as the best fit for my primary client's enterprise environment, so I've been working through a few things to make this a manageable, extensible, quickly deployed solution for a wider swath of development needs. This is a brief discussion of the high-points of that journey. While I'm mostly only taking advantage of Angular 6 functionality, I've been using the Angular 7 CLI to make sure I've got the latest dependencies in the applications I am building right from the start.


The first thing I like to do after nailing down the tool chain for any new technology I am learning is to create a Proof-of-concept implementation. In this case, we had a simple 3 page survey tool that was used once a year for an internal campaign. For the new year, they wanted to add a leader board with bar charts and add email notifications.

Translating the current work from .jsp based web pages to a modular design took a lot of effort, but less time than I thought it would. The first big surgical decision was to separate the UI and the back end web application that provided the APIs driving the user experience. This decision played well into the next section of this article when it came time to break things out into libraries.

The form this separation took, within my Maven project, was that of a multi-module project. Maven is a dependency management and build tool that makes combining external dependencies with your own code a pretty straight-forward, declarative affair. By extension, then, making your own modules should follow roughly the same approach. It does, to an extent, but what you inherit is the responsibility for creating the packaging for your own sub-modules -- a task usually transparent to you when you consume externally provided dependencies.

So in this case, I had separate Maven build files for the API, the UI, and a Web module which simply provided the Web Archive (.war) file packaging at the end of the build. With this arrangement, a web developer can maintain the UI and a back-end engineer can maintain the Spring API separately without excessive concerns for one another's activities.

The POC was a success, and it also created the opportunity to begin identifying and isolating our own unique Angular components as reusable libraries.


Abstraction, if you're not familiar with the term, is the practice (art / science) of breaking a system down into representational components that serve a single purpose in a generic enough fashion as to be useful in many different scenarios. Selecting a function to extract from my POC for this treatment was not my biggest challenge. Getting the process nailed down, from an Angular world view, was what required the most work.

Angular provides external library components to you through NPM. NPM is the Node Package Manager and is by default pointed to a global internet library of Node Modules. If you want to publish your own modules to NPM, you have to sign up for an account. For an enterprise environment, this may not be the best approach. In some cases, components you develop are going to be useless outside of the environment you are working in. In others, they may represent portions of intellectual property that can not be shared. So I had the challenge of working out how to do this without the NPM repository.

The first step was to create a library project. There are several guides available online for this. What this process taught me was the need to carefully decouple my angular components. While Angular makes it super easy to add components to a project with the Angular CLI, you want to be careful what you do with them after that step in terms of how they are connected to parent components. While it is possible, for example, to make components out of form elements, turning one of those elements into a standalone library means you won't necessarily have the parent context while developing and testing that library. Creating them in a way that they have a minimum of interaction with the parent component, then, predisposes them to future extraction into standalone libraries.

The next thing was figuring out how to both put the library under source control and provide a path to being able to package and install it into another future application. This involved three steps.

First, only the "lib" folder in the library component is checked in. Checking in the surrounding test harness is not required.

Second, creating an on-board packaging script for the library allows future users to build it into a .tgz locally after they clone the repository.

Third, using an NPM feature to install from a local file path, the .tgz can be installed as though it comes from the global NPM repository.

This seems like a lot of work, but the important thing here is that it keeps the source code for the library open for extension and modification within the enterprise. I want future developers to be able to fork this library to make their own components or branch the code and possibly submit pull requests when they fix bugs. By keeping the library in a raw, source code format, we get the best features of using packaged libraries and reusable code combined.


Going forward, I have a couple of targets I want to hit with my Angular learning. I have a request to expand the libraries that are documented and tested - essentially create a loose standard for us to follow within the enterprise, so expanding my knowledge of existing external components is going to be a major theme in the coming months. Secondly, I have been delving into Android development on the side. Angular, through Native Script, promises to expedite the process of developing tools that can work on multiple platforms, including Android, so I'll be looking at that.

Here are some of the resources I've found thus far that have been useful to this pursuit:

Making custom libraries

More in-depth example for making libraries

No comments:

Post a Comment