Create Your First Angular Library — Beginner Guide
When our projects become larger, we may have to split them into sub-projects and share some common behaviour. That’s where libraries can be useful. In this article, I will talk about the overview of libraries, creating a library, using it locally in an application and how to publish it to npm.
With the introduction of Angular 6, the library creation process has become tremendously easy. We are using Angular CLI throughout this article to generate, build and run Angular applications.
If you want to add a new library to an existing project, you need to at least upgrade it to v6.0.0. Read on how to update here.
What is an Angular Library?
A library is a collection of functionalities that we are going to use in multiple applications. So, a library provides,
- reusable functionalities
- sharable code
- tightly coupled code for specific features
An Angular library is also an Angular application, but it cannot run its own. Another application should import it and use it. An Angular library consists of modules, components, services, etc. Angular Material is a perfect example of a general-purpose library that provides reusable components.
If you have a common feature that you need to include in multiple applications, a library would be an ideal solution. For example, let’s assume that you need to create a button that redirects to a company website and you need it in multiple applications, then it would be better to place it in a library first and import it from there.
Creating a library
First, we need to create a workspace before creating our library. A workspace can be a home for multiple libraries and multiple applications. A command to create a workspace is:
ng new <workspace-name> --create-application=false
Note that I have set the create-application
flag to false here. If we don’t set the flag to false, Angular CLI will automatically create an Angular application, not a workspace.
When you observe the file structure in the workspace, you will notice there is no src folder. If you want to learn more about these created files, take a look at Angular file structure documentation.
The next step is creating a library. To create a library, run the below command in the workspace. (Don’t forget to CD
into the workspace)
ng generate library <library-name> --prefix <prefix-name>
It’s a good idea to check if the library name is already taken on https://www.npmjs.com if you are hoping to publish it to the NPM registry, so you don’t have to change it before publishing. Package names must be unique in the npm registry and anyone can publish a package. As for the flags for this command, if you don’t set a prefix it will default to lib
. All the components, services, directives you create inside this library will be named with the prefix you provide.
The above command creates a projects folder with your lib folder inside it.
Now, you can create as many components in your library using:
ng g c <cmp-name>
Using Angular Library components
You don’t need to publish the library to an NPM registry to use it in the same workspace, but you need to build it first. You can build the library via the below command.
ng build <library-name>
Running this would create a dist folder for your library. You’ll notice 3 package.json files here. One is in the workspace level, another one is inside the library project and there’s another package.json inside the dist folder. Let’s discuss this in detail later.
We can add a script also in place of doing this manually(in the root package.json).
"build-lib": "ng build <library-name>"
Now, all you need to do is create an Angular Application in the workspace(You can create this application inside the same workspace or a different workspace, but for now, I’m creating this inside the same workspace we created the library). Go to the workspace folder and run the below command.
ng g application <application-name>
Then go to the app.module.ts
and import the library by name:
import { MagicLibModule } from 'magic-lib';
Use the library component in one of your application components and observe the result by running the Angular app using ng serve
.
Rebuilding the Library
Do some changes in library components. At the moment, every time you do a change to your library components, you need to rebuild it in order to see the respective changes in the main application, which is tedious. Let’s see how we can use the --watch
flag to overcome this problem.
All you need to do is build your library using the below command. If you are using a build script, update the script there.
ng build <lib-name> --watch
Now make any code changes in your library and save it. It will automatically reflect in your target application as we have run the library in “watch” mode.
Packaging the Library
Earlier, we used our library component inside the same workspace. But, how we can use it in the angular applications which are not created in the library workspace? The obvious solution for this is publishing our library components to an npm registry. However, we can do a small trick manually to see the library components in other Angular applications.
We need to pack our library first. To pack the library, go to the library distribution directory and run the below command.
npm pack
This would create a .tgz package for the library which is to be exported into other applications we will be using.
We can add a script for this in the root package.json as below.
"pack-lib": "cd dist/lib && npm pack"
Then, create a new angular application and install your library as below.
npm install <path-to-tgz-file>
Check your package.json to see if it has been installed and is reflected inside the dependencies.
You will notice it being added as a file just like this:
The next step is to import the module of your library and use the component.
import { MagicLibModule } from 'magic-lib';
This should give our project access to the components declared inside this module. We can now use the component directly on the template and see how it works!
On the template,
<section>
<tc-magic-cmp></tc-magic-cmp>
</section>
And there you go!
Publish Library to NPM Repository
Now, our library is almost ready to be published, but there are a few updates that are still required. A detailed description can be found from the official source. I am just going to highlight a few important ones.
- Follow the naming convention for NPM packages and make your library unique. An easy way is to name your library as
@<your-username>/<library-name>
- Need to update the
package.json
file with additional details such as author, GitHub link, etc. - Don’t forget
README.md
andLICENSE
file. TheREADME.md
file will be the documentation that will be displayed on the npm website. You need to provide detailed information about your APIs and other information for your users in theREADME.md
file.
Don’t forget to build the library again after these changes and use --prod
flag to build the library.
The next thing you need to do is have an account on the npm registry. You can create an account in 2 ways. Using
npm adduser
in the terminal or creating an account through the official site. If you created a user account on the site, usenpm login
to access your account from your terminal.Type
npm whoami
from a terminal to see if you are already logged in.
All you have left to do is publish the library.
npm publish dist/<lib-name>/<lib-name>-0.0.1.tgz --access public
Go to npmjs.com and check your published library there.
If you’re getting a 403 Forbidden error, most probably, you need to verify your email address. Go to your email which you used to create NPM account and check the email you got.
Bonus:
peerDependencies inform your consumers about the compatible versions. By adding a package in peerDependencies
you are saying the package is compatible with this version of the package. Read more about dependencies and peerDependencies here. Use semantic versioning to version your library following the major, minor, patch version specifics. Read about SemVer here.
Finally,
I’m going to write a separate article to explain about reusability of library components and best practices. Stay tuned for more updates.
Connect me on Twitter.
Thank you for reading! 🤗