Angular lazy loading retro: Module ➡ Component ➡ Deferrable View

Angular 17 released Deferrable Views🔥 While Angular docs excellently covers what Deferrable Views are and why they are beneficial, here I’d like to take a look back at module & component lazy loading and tie that together with deferrable views (a part of component’s template).

Enterprise apps should be split into Feature modules

The correlation between the size of the build output bundle and the Time to First Bite (TTFB) is obvious. A larger bundle takes longer to load, impacting the user experience (try to put ALL in the root module and check the bundle size😀). To counteract this, we distribute code across modules, resulting in smaller, more manageable output bundles. Just a common practice of code organization (nothing Angular specific).

Module ➡ Component ➡ Deferrable View

With the introduction of standalone components, we do the same – distribute code into components. The module is a container for components, directives, and pipes. So, lazy loading of standalone components was a step in reducing that initial bundle.

Angular’s innovation doesn’t stop at lazy loading components; it extends to deferrable views. By enabling the loading of specific parts of a component’s template on demand, Angular provides developers with the tools🗡 for even more granular control, further refining the user experience.

Triggering Deferrable Views

Angular offers multiple options to trigger the loading of deferrable views. Loading on idle (default), hovering, or based on user interactions such as clicks or keydown events makes templates more dynamic and interactive. These options not only enhance the user experience but also allow developers to tailor the loading behavior to suit specific use cases. Check Angular docs for samples👋

Feeling Angular’s Renaissance

⚡Electrifying talk by Mark Thompson yesterday in front of NorthWest Chicago JavaScript🔥

Most of the JavaScript devs audience were not Angular fans.

It was interesting to watch the audience converting from skeptics (still holding a grudge for Angular 2 migration) to believers🕊🙂

Deferrable views was a hit, more performant change detection with Signals, standalone components (smoother learning curve), SSR, …

Mark Techson, as always, radiated tons of positive energy while sharing Angular awesomeness knowledge. It felt like it was enough to charge the whole building ⚡⚡⚡ (or a block 😀), not just devs in the conference room😁

“Go build great apps!”🚀

feeling #AngularRenaissance❤

Angular DevRel talk

🔊 Angular DevRel Mark Techson is back in town🔥

See you on Thursday for his talk at NorthWest Chicago JavaScript:

“The web is changing and Angular is changing to meet the needs of the modern web developer. But how is Angular changing? What features are available to help you build the next generation of Angular web apps? Come to this session to learn how Angular is evolving to enable developers to build dynamic web applications across the web stack. You’ll find out why there has never been a better time to develop web apps with Angular.”

#AngularChicago

Project Graph in Nx

Introduction

In this blog post, we will explore the benefits of using the project graph tool provided by Nx to visualize applications and libraries in a monorepo. Enterprise applications consist of multiple apps and libs, which can quickly become complex and hard to navigate. The project graph feature in Nx comes to the rescue by offering a visual representation of dependencies, making it convenient for team members to work with the codebase, even if they joined the project at a later stage.

Ensuring Code Quality with Project Graph

The project graph not only helps in visualizing the monorepo but also aids in maintaining code quality. It enforces linting rules defined in the eslint configuration file, ensuring that any new library added to the workspace adheres to the specified rules. To maintain order and prevent chaos, you can refer to a good initial set of rules below (github link here).

Overview of the Monorepo

nx graph command outputs graph below. Our monorepo contains two main applications: trucks and admin. Additionally, each application has associated e2e test projects, totaling four apps. We also have two libraries: shared-common-ui and trucks-feature-trucks. Let’s dive into more details about these libraries.

Understanding Library Tags

shared-common-ui library contains the BannerComponent, which is shared and used by both applications. The library is appropriately tagged with scope:shared and type:ui making it self-explanatory. The tags array is defined in the project.json file generated by Nx schematics. Specifying tags helps enforce module boundaries and brings clarity to the development process. Nx suggests this convention based on their project delivery experience.

Tags scope:shared, type:ui, and others mentioned in this post adhere to time-tested conventions. Consistency is key in any software development endeavor. By adopting these conventional tags, you ensure that every team member understands the purpose and context of different libraries. However, they are arbitrary strings. And you can come up with your own tags if you’d like.

Code Organization and Naming Conventions

In trucks-feature-trucks library, we are implementing the feature of displaying a list of trucks for the user. Following the convention of grouping libraries per scope, we named it trucks-feature-trucks. The name may not be the best, but adhering to the convention makes it more comprehensible.

Properly Tagging Libraries

Container/smart components like TrucksComponent belong to libraries tagged with type:feature

TrucksComponent is going to have a child component named TruckDetailsComponent. This child component serves as a presentation/dumb component, it communicates with its parent via Inputs/Outputs. Such presentation/dumb components are placed in libraries tagged with type:ui.

When making http calls to retrieve data, it’s essential to separate data access logic from components. This code should be placed in lib(s) tagged with type:data-access. These libraries are responsible for handling data retrieval and manipulation, ensuring a clear separation of concerns within the application.

For commonly used methods that format strings (e.g., capitalize First Last name, format currency, or handle dates in a specific way), creating libraries tagged as type:util is recommended. Methods within type:util libraries solve common issues and are excellent candidates for reuse. To express this intention clearly, consider adding the tag scope:shared to these libraries. This way, developers can easily identify and utilize shared utility functions, further promoting code efficiency and consistency.

Benefits of Conventional Mapping

Following this conventional way of mapping requested features into well-defined units of code brings several advantages. It aids in maintenance, code ownership, testing, accurate estimations, and faster delivery with higher confidence. As a result, it boosts the return on investment for the project.

Conclusion

In conclusion, utilizing the project graph tool provided by Nx simplifies the management of monorepo projects significantly. It not only offers a visual representation of the codebase but also ensures adherence to linting rules, maintaining code quality. By following consistent naming and tagging conventions, developers can enhance the scalability, organization, and maintainability of the application, leading to a more productive and successful development process.

Nx library types; 4 is enough

Build enterprise applications Nx time faster in smaller categorized chunks.

There could be different ways to deliver enterprise applications. Every approach would have pros & cons associated with it. We would definitely need to be able to see a big working thing in separated chunks. This allows us to assign those chunks to team members, deliver in parallel, get ownership, etc. What’s the best way to slice this pizza? How to define boundaries?

After a few projects, meetings on best practices, facing real results, one could come up with his/her own way of building & separating concerns.

Nx did that. This system provides default opinions on separating concerns, testing, linting (and much more) to deliver projects with confidence. It also provides flexibility to make your own alterations if needed. And these are production tested opinions of a talented team led by 2 ex-Googlers actively listening and interacting with the dev community.

Let’s look into how to separate concerns in our codebase.

Nx provides monorepo to organize code. Organize & scale like Google, Meta, Twitter, Uber & Airbnb with their team sizes, volume of daily contributions, and variety of frameworks & tools used to deliver.

monorepo has projects: applications & libraries.

application is a container to bundle & compile libraries for further deployment. The less code goes in here, the better. Heavy lifting is done by code in libraries.

Nx suggests 4 types of libraries: feature, ui, data-access, util. These are defaults. How much value in these defaults💰! Most of front-end code we write should fall into 1 of these library types. Yes, you can come up with additional library types. (However, thoughts can often lose clarity when entities multiply. Brevity is the soul of wit 🙂)

So anytime we need to design our front-end app, we could come up with the necessary number of libraries. Having 4 types of libs in mind, allows us to slice this pizza faster & assign libraries across the dev team. Work in parallel, track progress easier & come up with better delivery estimates.

library types are defined by tags. They are the source for Nx to build our project graph. Project graph is going to throw errors if circular dependency is found or other dependencies do not make sense. Another boost of confidence while adding to our codebase. We are going to talk about project graph in the next post…

Nx 16.5 release

Nx 16.5 was released on Jul 6, 2023:

  • ~2x Cache Perf Gains
  • Tag-Based Task Running
  • nextjs 13 support
  • Angular 16 Support
  • verdaccio npm support
  • CLI creation feature
  • New Input Type: External Deps
  • New Lint Rule: Package Dep Checks
  • New Interactive Changelog

Details here

Migrating from AngularJS to Angular

Upgrading from AngularJS to Angular is like building a bridge between 2 frameworks. 

Webpack is going to create a bundle for a browser. In our webpack configuration file we specify an entry point, usually named main.ts

On our entry we are going to do a few things:

  1. Bootstrap Angular root module (aka raising the first framework). 
  2. Our root module imports UpgradeModule from ‘@ngular/upgrade/static’. UpgradeModule is a bridge between Angular & AngularJs. 
  3. UpgradeModule exposes bootstrap() method to bootstrap AngularJs module (aka raising the second framework).

Two frameworks are up & running side by side. They are connected with the bridge. We are in hybrid mode.

One more thing that is going to happen on entry: Register Angular component as AngularJs directive from a specific AngularJs module.
We are going to use this bridge between 2 frameworks to migrate pieces in both directions. For example, we can now add our 1st Angular component in hybrid mode, that component can use AngularJs service.

Custom vs Ready-to-use controls; Kendo UI

I still hear debates on which way to go. I can imagine a scenario where you might need to build your custom control or even controls suite. And if application screen mockups are created, approved and promised without a development/coding team, the custom control scenario chances go higher. That usually ends up in more expensive products.

In case your business is not selling controls, they are tools to solve the problem and the problem to be solved. And probably it’s better to take a step back and check how existing tools can solve one’s business problem in an application.

The final product most likely is going to end up being more reliable, powerful and less expensive when the existing library is used.

I think picking that one control library should go after the main idea of the application and its core functionality, but before describing detailed functionality, look and feel of your application. 

This should reduce the risk of developers burning time on customizing ready-to-use controls versus using those controls to solve a business problem.

For the last few years, I’ve been having a good time with Kendo UI for Angular controls.

I picked Grid as an example. It is a powerful control that is needed in most applications.

We need node.js and @angular/cli to start Angular app. If you never started an Angular app, the style guide is probably the best place to go.

I created youtube playlist. You can watch the whole thing or go to the piece below you’re interested in.

We’ll ng new kendo-grid application & serve it with ng s -o. Click here to watch the video

Clear some markup, ng add @progress/kendo-angular-grid video

Kendo UI for Angular grid filtering, paging, sorting video

Angular checks types in templates strictly, compiler reports errors; errors fix video

Add Angular feature module, generate component in it, move grid inside that component video

Reinventing a wheel is expensive. Your great app idea comes first; second, decide on the library of controls (Kendo is a good one :)) and other tooling; third, promise screen mocks with specific behavior, look and feel to your customers. It is going to result in faster, smoother delivery of the product video