Search code examples
angularangular-libraryng-packagr

Angular 9 library with subentry points circular dependency


I have a very specific question about angular libraries secondary entry points setup. I really don't understand how i can setup it to get it work when they depend on each other including the main entry point. I've read the docs for the ng-packagr and a lot of issues and stack questions but found no really good answer. The thing is that i want to break up our large grown internal library into smaller pieces so that the imports and dependencies getting smaller for apps that don't need everything.

So here is just what i want to reach:

  • Main lib @my/my-lib
  • secondary path @my/my-lib/functions
  • secondary path @my/my-lib/constants
  • secondary path @my/my-lib/lang
  • secondary path @my/my-lib/broker
  • secondary path @my/my-lib/signalr
  • secondary path @my/my-lib/sso
  • secondary path @my/my-lib/types

and thats the folder structure:

projects\my-lib
-- constants\
---- ...
---- package.json
---- public_api.ts
-- functions\
---- ...
---- package.json
---- public_api.ts
-- lang
---- ...
---- package.json
---- public_api.ts
-- broker
---- ...
---- package.json
---- public_api.ts
-- signalr
---- ...
---- package.json
---- public_api.ts
-- sso
---- ...
---- package.json
---- public_api.ts
-- src <-- the main entry point, as setup from the ng g library
---- lib
------ modules <-- the old ones from where i want to source parts out in secondary paths
-------- auth
-------- config
-------- footer
-------- header
-------- log
-------- state
-------- ...
---- public_api.ts
-- ng-package.json <-- main entry point
-- package.json <-- main entry point

Now here is my problem:

The first two, constants and functions, are working just as expected, because they have no dependencies on anything.

Now when i want to import something from @my/my-lib/lang in the main @my/my-lib and reverse i get a circular dependency warning on itself. That sounds in the first place logical for me because the ng-packagr don't know which to build first.

What i've read so far was that the secondary entry points getting build first everytime, this would work perfectly when i dont't have dependencies from @my/my-lib/lang to services back inside @my/my-lib, so how can i setup this that i can import things in @my/my-lib/lang from @my/my-lib and reverse?


Solution

  • From my experience the secondary entry points are built after the main entry point if you are using Angular CLI. The only possible references you can have is to reference the main library from the secondary entry points. You can have references between the secondary entry points again only in one direction. During build the references are resolved and the build order of secondary entry points is determined so they are build in the order of reference.

    For your example the only thing you can do is import things from @my/my-lib inside the @my/my-lib/lang and then in @my/my-lib/lang import for example the @my/my-lib/types.

    The import should be to the library not the file directly.

    import { MainLibClass } from '@my/my-lib';
    import { MyType} from '@my/my-lib/types';
    

    Secondary entry points are like another independent library inside the main library that builds on top of it or that provides some independent functionality that is connected to the main entry point. That is why like with libraries you can never have a reference in both directions.

    More I cannot say since you don't provide any information why you need references to go in both directions. From what I see from your design it is probably better you create separate libraries for for each part you have now made a secondary entry point.