Friday, June 25, 2021

How To Build Reusable Angular Components And Share Them With The World

 

As you probably know, Angular is all about building UI components. There are several excellent component libraries out there that you can use to build your own application, such as Angular MaterialClarity or Kendo UI to name a few.

Such libraries provide common reusable components such as tabs, date pickers, collapsible menus, and much more. Still, there’s always a time where we need something more customized and more adapted to the specific needs of our project.

If you ever get in that spot where you want to create a component that might be reused in different projects, or if you want to write components that you would then open-source, this article is for you.

What is a Reusable Component?

Angular was designed to promote code reuse. As a result, the recommended component architecture relies on two different kinds of components:

  • Container components (or “smart” components) know how to get data and work with services
  • Presentation components (“dumb” or “lazy” components) that have to be fed with data

Container components are tied to the business logic of your application. They are not meant to be shared or reused. Instead, what they do is get data from the server and pass it down to presentation components.

Presentation components do not know about any service. They are pure, simple UI components that just need some input data to render. Buttons, tabs, headers, tables are all great candidates to be used as presentation components. As a result, such components are reusable because they are coded in a way that is not tied to any runtime context.

Here is an example of such component:

@Component({...})
export class MyComponent {

   @Input()
   data: Data;

   @Input()
   text: string;

   @Output()
   onButtonClick = new EventEmitter<Data>();
}

And the HTML template for that component would look like this:

<h2>{{data.title}} </h2>
<img src="{{data.picture}}" class="img-fluid">
<p>{{data.description}}</p>
<div>
   <button role="button (click)="onButtonClick.emit(data.id)">
       {{text}}
   </button>
</div>

Presentation components are really just an HTML template that has to be filled with data. They can also emit events that container components would catch in order to make the actual business logic happen.

Here is an example of a typical component architecture that illustrates this:

Component Architecture in Angular

Most shareable components will be presentational components, so that we can use them in different contexts.

The only exception to this would be a component that performs a specific task to render some data. For instance, if you want to create a weather widget that renders the current weather conditions of a given location, that specific component might have its own business logic to retrieve its data from a weather API.

Now that we know what are the characteristics of a properly written reusable component, let’s see how to write one that we can share with the rest of the world.

How to Share a Component with the Rest of the World?

This specific task became very easy with Angular 6. In Angular verbiage, what we need to do in order to create shareable code is package it as a library.

As always with Angular, CLI comes to our rescue to assist with this:

ng generate library [name of the library]

The above command creates a new sub-project in your code repository, that you would find under projects/[name of the library].

Once you’ve done that, you can create your component within that library. Here again, the Angular CLI can take care of that task. All we have to do is indicate that the component has to be generated in that library:

ng generate component [component name] --project [name of library]

Another important thing to know is that the public API of your library is defined in projects/[name of library]/src/public_api.ts. You should update this file to export the public definitions of your API - as well as add your component to the exports section of your library’s Angular module file:

/*
 * Public API Surface of the library
 */
export * from './lib/[name of library].service';
export * from './lib/[name of library].component';
export * from './lib/[name of library].module';

In order to build your library, the Angular CLI again is there to help:

ng build [name of library] --prod

How does this make my component public?

It doesn’t - not quite yet. The final step if you want to open-source your component is to publish it on NPM. You need to create a NPM account, then use npm login in your Terminal.

Once you’re logged in, you can make your library public with the following set of commands:

ng build [name of library] --prod
cd dist/[name of library]
npm publish

And that is it! Your component is now available for download with NPM. You can read more about publishing on npm here: https://docs.npmjs.com/getting-started/publishing-npm-packages

Whenever you want to publish a new version, just update the version number in projects/[name of library]/package.json and run the above three commands to publish the update.

What if I want to share my component locally with other applications, not publicly on the internet?

Then your best option is to use a mono-repository architecture, where all of your Angular projects would be in the same Angular master project. It is also a feature supported since Angular 6, where you can have multiple applications (and libraries) in the same repository.

All of these different applications would be located in the projects folder, just like libraries.

Once you’re set-up that way, importing code from shared libraries is just one Typescript import away:

import { something } from ‘[name of library]’

We covered all of the basics to get you started with shareable components in the Angular world. If you ever open-source your components thanks to this tutorial, feel free to let me know!

No comments:

Post a Comment

Technology’s generational moment with generative AI: A CIO and CTO guide

 Ref:  A CIO and CTO technology guide to generative AI | McKinsey 1. Determine the company’s posture for the adoption of generative AI As us...