Paths to 3rd party library with angular app and custom library

43 views Asked by At

Environment Setup

Currently running on Angular v16.

I have my custom Angular library (lets call it MyLib), which is not public and it is essentially a bundle of services and components I am using in other projects of common nature. So I have it locally in its own folder and Angular workspace.

Then I have one of the Angular projects using this library (lets call it MyApp). It is also a separate Angular workspace in its own folder.

From MyLib I am exporting its main module, and importing it in MyApp. Since they are not in the same workspace, I have to give MyApp the path to MyLib in its tsconfig.json file like this:

"paths": {
  ...
  "my-lib": ["../portal-libs/dist/my-lib"]
}

Everyting works fine.

Problems

Now I needed to add some third-party library, that both MyLib and MyApp are using. The NgBootstrap is a good example. I install and include it in both MyApp and MyLib. But now, depending on where from I use the library, I run into (runtime) errors.

For example I have a InfoModal component in MyLib, that uses the NgbActiveModal from NgBootstrap library. If I use the InfoModal component from within MyLib (ie. calling a service located in MyLib, that creates the InfoModal), everything works fine. But when I use the InfoModal component from some service/component located in MyApp, I get the error:

 ERROR NullInjectorError: R3InjectorError(AppModule)[NgbActiveModal -> NgbActiveModal]: 
  NullInjectorError: No provider for NgbActiveModal!

suggesting there is no provider for the NgbActiveModal.

What in the end solved this issue was to go to the tsconfig.json file of MyApp again and add the path to the NgBootstrap library that MyLib is using:

"paths": {
  ...
  "@ng-bootstrap/ng-bootstrap": ["../portal-libs/node_modules/@ng-bootstrap/ng-bootstrap"],
  "my-lib": ["../portal-libs/dist/my-lib"]
}

Now it all works fine again.

Question

Now my question is, why I need to point MyApp to the library files that MyLib uses??? I would understand if I needed to export NgbModule included in MyLib, so that it would get included into the MyApp along with the MyLib module and they would share the "same instance of the library" as I picture it (but that doesn't work).

This way it is confusing for me, because I had the idea, that library files are essentially like blueprints of what to create. And when the Angular app starts, it actually creates instances of all the services, components etc. according to these blueprints, but it should not matter where these blueprints come from. The created instances are what matters and they reside in the Application memory from where they are used in the App itself. Isn't that so?

I presume, if I had MyLib public on the NPM for example, I'd install it into MyApp the normal way from the NPM server, thus it would reside alongside other libraries in the node_modules folder. Then all the libraries in the node_modules forlder would be the same for MyApp and MyLib and I would not run into this problem.

I wasn't able to find a source that would explain this behaviour and I can't wrap my head around it. So please If someone could point me in the right direction or shed a little bit of light on how the library files are treated?

0

There are 0 answers