Description of the issue
I have an Angular (version 15.2) workspace, that has an host
app, three modules
and two libraries
.
This structure shows what is being used by what:
host
moduleA
library1
moduleB
library1
library2
moduleC
library1
library2
The host
lazy-loads the three modules in this way:
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
const routes: Routes = [
{
path: "a",
loadChildren: () => import("a").then(m => m.AModule)
},
{
path: "b",
loadChildren: () => import("b").then(m => m.BModule)
},
{
path: "c",
loadChildren: () => import("c").then(m => m.CModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {
}
Each of the three modules use library1
and/or library2
, as shown in the structure at the beginning.
The lazy loading works as expected, meaning that when I navigate to “localhost:4200/a” I can see from the network that I only get moduleA.js
(of course with the name generated by Angular).
Naturally I also see the file common.js
that, as I was expecting, contains all the code from library1
used in moduleA
, moduleB
, and moduleC
.
The problem is that this common.js
file also contains the code from library2
, that is only shared by moduleB
and moduleC
. This causes the browser to load code that is useless in that moment and invalidates (although not entirely) the purpose of the lazy-loading system.
Therefore I was wondering if among the angular configurations there is something to add or change in order to obtain a different bundle for each library.
Desired result
The desired result is that when navigating to “localhost:4200/a” the browser would download moduleA.js
and an library1.js
. Then when navigating to “localhost:4200/b”, the browser would download moduleB.js
, library2.js
, but not the library1
that has already been downloaded.
What I’ve already tried
I have already explored solutions like the angular options vendorChunk: false
, commonChunk: false
and then tried to use webpack’s SplitChunkPlugin
via the angular json.
With the SplitChunkPlugin
method I was able to obtain a common.js
file that contained only the code of the library1
, that is used by all of the lazy imported modules, but the code of library2
was repeated in moduleB
and moduleC
.
This is what my custom webpack config looked like:
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
library1: {
test: /[\/]projects[\/]library1[\/]/,
name: 'library1',
chunks: 'all'
},
library2: {
test: /[\/]projects[\/]library2[\/]/,
name: 'library2',
chunks: 'all'
}
}
}
}
};