Creating multiple Angular libraries/packages is crucial for organizing code efficiently. In this case, I have developed three distinct packages:
@example/ng-youtube-player
: includes aYoutubePlayerComponent
and the associatedYoutubeApiService
@example/ng-dailymotion-player
: consists of aDailymotionPlayerComponent
along with its correspondingDailymotionApiService
@example/ng-vimeo-player
: houses aVimeoPlayerComponent
alongside the necessaryVimeoApiService
As part of my ongoing development process, I aim to construct a new library featuring a universal VideoPlayerComponent
. To achieve this, I intend to utilize only the services provided by the YoutubeApiService
, DailymotionApiService
, and VimeoApiService
packages. Separating these service classes from the complete libraries will streamline installations and minimize unnecessary component inclusion.
Although angular's tree-shaking functionality theoretically prevents unused components from being bundled into the application, I prefer keeping dependencies isolated for clarity.
In an attempt to realize this vision, I ventured into setting up a monorepo containing two libraries and a testing application. However, encountering build failures upon referencing a service from another library prompted me to create a simplified workspace for issue replication:
git clone https://github.com/PieterjanDeClippel/angular-monorepo-test
cd angular-monorepo-test
npm install
ng build @mintplayer/ng-youtube-api
ng build @mintplayer/ng-youtube-player
ng build ng-youtube-player-demo
# All projects compile successfully
# Now go to the NgYoutubePlayerComponent and uncomment the injection parameter in the constructor (line 16)
ng build @mintplayer/ng-youtube-player
The build subsequently failed, inundating the console with numerous errors similar to the following:
✖ Compiling with Angular sources in Ivy partial compilation mode.
projects/mintplayer/ng-youtube-api/src/lib/ng-youtube-api.service.ts:1:1 - error TS6059: File 'C:/Users/user/source/repos/Tmp/mintplayer-ng-youtube-player/projects/mintplayer/ng-youtube-api/src/lib/ng-youtube-api.service.ngtypecheck.ts' is not under 'rootDir' 'C:\Users\user\source\repos\Tmp\mintplayer-ng-youtube-player\projects\mintplayer\ng-youtube-player\src'. 'rootDir' is expected to contain all source files.
1 import { Injectable } from '@angular/core';
projects/mintplayer/ng-youtube-api/src/public-api.ts:1:1 - error TS6059: File 'C:/Users/user/source/repos/Tmp/mintplayer-ng-youtube-player/projects/mintplayer/ng-youtube-api/src/public-api.ngtypecheck.ts' is not under 'rootDir' 'C:\Users\user\source\repos\Tmp\mintplayer-ng-youtube-player\projects\mintplayer\ng-youtube-player\src'. 'rootDir' is expected to contain all source files.
Evidently, two primary issues emerged during this process:
- Each project must be built separately in the correct sequence
- Libraries cannot directly utilize services from other libraries
Despite exploring related questions on this matter, such as 'rootDir' is expected to contain all source files, definitive solutions remain elusive.
Code
To examine this conundrum further, refer to my test code hosted here. Detailed instructions for reproducing the issue are available within the aforementioned repository. Key modifications made to the root tsconfig.json
file are outlined below:
{
...
"compilerOptions": {
...,
"paths": {
"@mintplayer/ng-youtube-api": [
"projects/mintplayer/ng-youtube-api/src/public-api.ts"
],
"@mintplayer/ng-youtube-player": [
"projects/mintplayer/ng-youtube-player/src/public-api.ts"
]
}
}
}
While successful integration between a library and application has been achieved without complications (as evidenced in the initial repositories mentioned at the beginning), challenges persist when attempting cross-library communication. Seeking guidance on resolving this deadlock and establishing a unified workspace housing two libraries and a test application is paramount.