12

Now I am building Angular library for defining reusable components. I made a component named main-layout. I needed to use ngx-perfect-scrollbar in the component. I know how to add dependencies in Angular project.

ng add [package name]

or

npm install [package name]

But I saw an article that says peer dependencies are added manually. so I added ngx-perfect-scrollbar in peerDependencies on package.json of the library I am developing.

enter image description here

After that, I tried to install npm packages in the root of the project.

npm install

then I noticed that ngx-perfect-scrollbar package did not be installed in node_modules.

Below is the full structure of my angular library project.

enter image description here

JS Guru
  • 343
  • 1
  • 3
  • 11
  • 5
    If you are following [Creating libraries](https://angular.io/guide/creating-libraries) handling peer dependencies is mentioned in the following section: https://angular.io/guide/creating-libraries#use-typescript-path-mapping-for-peer-dependencies . That being said, effectively anywhere you are consuming this library, you need to to `npm install ngx-perfect-scrollbar` at the base of your workspace which will provide ngx-perfect-scrollbar to your `my-work-showcase`. – Alexander Staroselsky Jan 27 '20 at 20:09

1 Answers1

32

You have two approaches of going about inserting dependency packages into your Angular library (package.json file) and both will work fine:

  1. "dependencies" (the library will bring this package in when you install the library)
  2. "peerDependencies" (When you add your library into the consuming project, you will be warned that you have to install this peer dependency yourself in your consuming project)

Which one is the best?

Short answer

The second one.

Long Answer

The second option is best and advised by Angular CLI even when you have packages defined in dependencies instead of peerDependencies. Here is the warning message Angular CLI (at least if you have a newer version of Angular - I have 12.x at the time of writing this) will show in the console when building: "Distributing npm packages with 'dependencies' is not recommended. Please consider adding to 'peerDependencies' or remove it from 'dependencies'."

However, there are a few differences and trade-offs between both of them and it is really up to you to decide which fits you most, but I am definitely going for the second option.

Approach 1 - dependencies

will simplify the setup in the consuming app as you will not see any warning about the peer dependency and you will not need to install the dependency manually. The issue you might have with this approach is that you may have version conflicts in the consuming app in case you already are using the same package in your consuming app. Let's say there is another package you have installed that uses the same peer dependency but in a different version. This approach also brings in performance concerns.

Approach 2 - peerDependencies

The second approach is probably the best of the two as all you need to do is to add the package in the peerDependencies and then when the library is installed in the consuming project, you will get a nice warning that you need to install the peer dependency manually. This approach feels a better practice in general as your application grows. Yes, you will get the warnings on library install, but you want to have as much control as possible over what versions of peer dependencies are installed in your consuming apps in the long run. Also you want to have small packages installed in your consuming app. This option is definitely safer and is the one I go for.

Here's a useful blog that also mentions this topic https://tomastrajan.medium.com/the-best-way-to-architect-your-angular-libraries-87959301d3d3

Interesting bonus fact

While I was learning about dependencies in Angular libraries, I have also discovered that when you go for option #2 above (peerDependencies), this does not necessarily mean that you will not need to have the dependencies in accessible in the library, otherwise Typescript will complain that it cannot find types.

Say you use are building your library in watch mode

ng build <name of library> --watch

This means that if you do not have the dependency packages installed (in the workspace where your library project files are) in the node_modules folder, Typescript will complain and build will fail. So, what to do in this case? Well, for me, the solution was to also add the required dependencies needed for the library to be built in devDependencies as well. Here is what I mean. This is my library package.json file at the time of writing this:

"name": "@alexrebula/ngx-giselle-ui",
"version": "0.0.8",
"peerDependencies": {
    "@angular/common": "^12.2.0",
    "@angular/core": "^12.2.0",
    "bulma": "^0.9.3",
    "@fortawesome/angular-fontawesome": "^0.8.2",
    "@fortawesome/fontawesome-free": "^5.15.4",
    "@fortawesome/fontawesome-svg-core": "^1.2.34",
    "@fortawesome/free-brands-svg-icons": "^5.15.2",
    "@fortawesome/free-regular-svg-icons": "^5.15.2",
    "@fortawesome/free-solid-svg-icons": "^5.15.2",
    "@googlemaps/markerclustererplus": "^1.2.0",
    "googlemaps-ts-rich-marker": "0.0.4"
},
"dependencies": {
    "tslib": "^2.3.0"
},
"devDependencies": {
    "@types/googlemaps": "^3.43.3",
    "@fortawesome/angular-fontawesome": "^0.8.2",
    "@fortawesome/fontawesome-free": "^5.15.4",
    "@fortawesome/fontawesome-svg-core": "^1.2.34",
    "@fortawesome/free-brands-svg-icons": "^5.15.2",
    "@fortawesome/free-regular-svg-icons": "^5.15.2",
    "@fortawesome/free-solid-svg-icons": "^5.15.2",
    "@googlemaps/markerclustererplus": "^1.2.0",
    "googlemaps-ts-rich-marker": "0.0.4"
}

See how I've literally duplicated the peerDependencies in devDepencencies? Except for Bulma (a CSS framework) of course, because not having CSS will not break the library compilation, I just need to install Bulma in the consuming app.

Credits and contribution

In case you would like to try out this study case, see te code or even collaborate with me on this learning path, I suggest you head on to https://www.npmjs.com/package/@alexrebula/ngx-giselle-ui and https://github.com/AlexRebula/GiselleUI. Any comment or feedback on what I wrote or did in my library would be great appreciated, especially if you think I have made a mistake somewhere along my discovery path. Thank you!

AlexRebula
  • 922
  • 2
  • 13
  • 26
  • Hi @AlexRebula. I appreciate your detailed and kind answer. I will definitely take the time to collaborate with you. – JS Guru Nov 17 '21 at 11:56
  • @AlexRebula Do you also these dependencies to the workspace package.json ? And do you run `npm install` from the library or the just the workspace ? – Dost Arora Jan 20 '22 at 14:58
  • Thanks for the clear explanation, I was looking for exactly the last part. Also solves the question asked easily. – Marcosaurios Jul 06 '23 at 09:06