I'm trying to structure existing code from an Angular Application to a shared Library. The Library should be used by other Applications as well. Therefore, i created multiple sub entries to structure the code to be tree shakeable.
Consider the following structure:
- lib
- entryA
- /src
- index.ts
- public-api.ts
- package.json
- entryB
- /src
- index.ts
- public-api.ts
- package.json
- entryC
- /src
- index.ts
- public-api.ts
- package.json
- ...
- ng-package.json
- package.json
Some entries are dependent to other entries (without a circular dependency). As an example EntryA
has no dependencies but EntryB
is dependent to EntryA
which is therefore imported in EntryB
.
The specific service is then imported in EntryB
:
import { MyService } from '@myorg/mylib/lib/entryA';
The path is resolved by the configuration in the tsconfig.json
file:
"paths": {
"@myorg/mylib/*": ["./projects/ui/*", "./projects/ui"],
"@myorg/mylib": ["./dist/ui/*", "./dist/ui"],
}
The build of the library works as expected and throws no errors. In the consumer Application the library is defined via the package.json
and imported in an angular module. The application wants to use EntryB
:
import { MyModule } from '@myorg/mylib/lib/entryB';
However, the build of the consumer application throws the error that it could not found the required dependency of EntryA
in EntryB
:
ERROR in The target entry-point "@myorg/mylib/lib/entryB" has missing dependencies:
- @myorg/mylib/lib/entryA
How can i handle dependencies between those sub entries?
I have found the solution and therefore answering my own question:
The problem was due to the different compilation. In Angular 10, Ivy is available for the application. But the library is not compiled with Ivy and should not be published with Ivy in the npm repository. An update to Angular 10 to enable partial
compilation could not be done due to dependencies.
There are three distribution formats that you can use when publishing a library:
View Engine (deprecated)—legacy format, slated for removal in Angular version 13. Only use this format if you must support View Engine applications. partial-Ivy (recommended)—contains portable code that can be consumed by Ivy applications built with any version of Angular from v12 onwards. full-Ivy—contains private Angular Ivy instructions, which are not guaranteed to work across different versions of Angular. This format requires that the library and application are built with the exact same version of Angular. This format is useful for environments where all library and application code is built directly from source.
See: https://angular.io/guide/creating-libraries#ensuring-library-version-compatibility
I have, since this is a private npm package, therefore set the build option enableIvy
in tsconfig.lib.prod.json
to true
for the production build. After the angular update the option should be set to partial
.