JBoothUA
JBoothUA

Reputation: 3149

How to bundle / include dependencies in Angular-CLI libraries

I'm having issues bundling dependencies.

My library package is a wrapper around @angular/material components.

I was surprised to find that everywhere I installed my library package also asked for @angular/material to be installed or I get an error.

There has to be a better way to do this right? I would like my package to be self-contained and "include" angular/material when it is installed.

I read that adding the following to the library's package.json

 "bundledDependencies": [
    "@angular/material"
  ]

should solve this issue, but it didn't seem to work, or at least there has to be another step, because then I see this error when I am installing my package:

is missing a bundled dependency "@angular/material". This should be reported to the package maintainer.

That error really makes it sound like I'm just missing something and this will work as I'm expecting. What am I missing?

I haven't been able to find any information on that error.

We would like to force the dependency to be installed to keep our library "modular" and self contained. In other words, we just want to install our library and automatically get all the dependencies that it needs.

We do not want to rely on the warning message from a peerDependencies.

It seems like this has to be a possible pattern, can anyone explain the point of bundledDependencies

Upvotes: 3

Views: 7737

Answers (2)

dhilt
dhilt

Reputation: 20754

By the end of 2021 it seems not possible to explicitly include the external dependency into the end lib's bundle using the standard Angular's out-of-box builder. This builder is ng-packagr, and there are issues about it in their repo: link1, link2, link3. The advise is to use rollup or whatever to re-compile the ng-packagr dists and inject the dependencies that need to be present there manually.

@sporritt Anyway just to be clear, there is no way now of bundling imports via ng-packagr, and there never will be. Correct?

@alan-agius4 At the moment no, this is not something that it is possible to do without an additional transformation after ng-packagr is executed.

My story is that I've already been using rollup for years in my Angular library (https://github.com/dhilt/ngx-ui-scroll) and it has one external dependency in its bundle getting there with my own custom build process. These days I was thinking it might be a good idea to switch to common practices and replace my manual rollup build process with the official ng-packagr approach. And I'm disappointedly stuck.

Let's see how this changes over time and hope that the workarounds mentioned above are helpful.

Upvotes: 1

G. Tranter
G. Tranter

Reputation: 17938

bundledDependencies is used to specify packages that you are including in your package. If you use that then you have to provide those packages in your bundle. They are distributed and installed as part of your package, not as separate dependency installations. See :http://npm.github.io/using-pkgs-docs/package-json/types/bundleddependencies.html.

An alternative, and I think the correct approach for libraries, is to use peerDependencies (that's what I use). This lets the library user decide whether or not they want to install those packages via their application's package.json, and will warn about "unmet peer dependencies" when installing your package but won't install them. This is useful because it allows the user to control the version of the dependent package. Angular Material specifies all of the various @angular dependencies that it requires as peerDependencies (see https://github.com/angular/material2/blob/master/src/lib/package.json).

If you want to force a dependency to be installed when your package is installed, just use dependencies. I believe this is generally not recommended for libraries.

Upvotes: 8

Related Questions