I've built an angular component library in an NX workspace. For several weeks I've been struggling to get my angular library to work properly. The library contains some 50 components with their respective module. I've asked a similar question some time ago, but still wasn't able to solve the problem. However I do have more intel.
All pages in my application are lazy-loaded. Each page demonstrates a component from the library. But just because I'm using the BsNavbarModule
in my AppComponent
and load the BsNavbarModule
in the AppModule
, javascript chunks from all other components inside the library are ending up in my main bundle.
All chunks in red should not be in the main bundle and are only used on lazy-loaded pages. The total size of the main bundle is 850 kB.
In my previous question someone suggested that this is because I'm using SCSS in my components like this:
badge.component.scss
:host ::ng-deep {
// Configuration
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
// Layout & components
@import "~bootstrap/scss/badge";
}
However commenting out :host ::ng-deep
everywhere does not get me rid of the javascript chunks in the main bundle, so that's not the solution I'm looking for.
The total size of my main bundle used to be 650 kB. But adding components to the library increased the main bundle with a staggering 200 kB up to 860 kB.
Moving all components to the application and removing the library, gives me something totally different. Doing so reduces the main bundle down to 400 kB.
It seems that angular workspaces now allow you to reference a library from another library, so I tested that as well. The results are the same, javascript chunks from all over end up in the main bundle just because I use one component from the library in the AppComponent.
I've commented out all SCSS in the library components. This does not affect the result in any way. The main bundle is still larger than 800 kB.
Up to this point it's become obvious that this has nothing to do with the SCSS, but rather with the fact that the components are inside a library. Using one component from the library bundles the entire library in the main bundle. The same phenomenon is explained, demonstrated and potentially solved here.
So I've added a ng-package.json to the folder of each component:
src/lib/badge/ng-package.json
{
"$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../../../dist/libs/example-ng-bootstrap",
"lib": {
"entryFile": "index.ts"
}
}
src/lib/badge/index.ts
export * from './badge.component';
export * from './badge.module';
and refactored the code to use this entrypoint instead of ../../..
import { BsBadgeModule } from '@example/ng-bootstrap/badge';
However, the workspace won't compile now. I've reduced the code to the bare minimum (seperate branch) with the information gathered from the previous link, and still the project won't build, but gives this error instead:
npm run build -- --skip-nx-cache --configuration production --source-map
> mintplayer-ng-bootstrap@0.0.0 build
> nx build "--skip-nx-cache" "--configuration" "production" "--source-map"
× 1/4 dependent project tasks failed (see below)
√ 3/4 dependent project tasks succeeded [0 read from cache]
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
> nx run mintplayer-ng-bootstrap:build:production
Building Angular Package
> NX Entry point @mintplayer/ng-bootstrap/core which is required by @mintplayer/ng-bootstrap/src/lib/badge doesn't exists.
Pass --verbose to see the stacktrace.
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
> NX Ran target build for project ng-bootstrap-demo and 4 task(s) it depends on (7s)
With additional flags:
--source-map=true
× 1/4 failed
> NX Entry point @mintplayer/ng-bootstrap/core which is required by @mintplayer/ng-bootstrap/src/lib/badge doesn't exists.
Pass --verbose to see the stacktrace.
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
> NX Ran target build for project ng-bootstrap-demo and 4 task(s) it depends on (6s)
With additional flags:
--source-map=true
× 1/4 failed
√ 3/4 succeeded [0 read from cache]
View structured, searchable error logs at https://nx.app/runs/IAaoSSkobF
What am I still doing wrong? Is ng-packagr not able to determine the build order of the entrypoints?