Share an external module between lazy loaded modules in angular2
Asked Answered
T

3

12

My app has components that use a heavy-weight external package (ag-grid, about 1MB) that is provided as an angular2 module (AgGridModule). I would like to load this package only when the components using it are required, so my ContentModule and all of its submodules are lazy-loaded. The whole structure looks like this:

enter image description here

However, when I import AgGridModule into both Submodule1 and Submodule3, it ends up being included in compiled JS twice, making both 1.chunk.js and 3.chunk.js large. I tried importing it into ContentModule, but then the submodules do not recognize the components that are included in AgGridModule, even if I list them in the exports property of ContentModule.

@NgModule({
  imports: [
    ContentRoutingModule,
    SomeOtherModule,
    AgGridModule.withComponents([])
  ],
  exports: [
    // this is the component from AgGridModule that I use
    AgGridNg2
  ]
})
export class ContentModule { }

Is there a way to share a module between lazy loaded modules, or to expose some components of an imported module to lazy loaded children?

UPD: Creating a shared module and importing it into submodules does not help, there are still two chunks with about 1MB each: enter image description here

UPD2: I solved the problem temporarily by merging Submodule1 and Submodule3 into a single module.

Tadich answered 24/1, 2017 at 11:35 Comment(12)
You should add the entire AgGridModule to the exports array. You can only export declarations within your ContentModule or entire other modulesExistence
@PierreDuc no, exporting the entire AgGridModule does not solve it, the component is still not being recognized.Tadich
How do you currently generate your build? angular-cli?Duologue
@AngularFrance yes, 1.0.0-beta.26.Tadich
Have you tried writing AgGridModule in imports array of ContentModule? As I am implementing the same scenario and working for me. P.S. I haven't created module files for child components.Officeholder
@BCoder yes, I posted the definition of my ContentModule in the question. How do you define routes to your child components, with children or with loadChildren?Tadich
I have defined routes with children. Like this: { path: 'auth', component: AuthComponent, children : [ { path: 'dashboard', component: DashboardComponent } ] }Officeholder
@BCoder then your submodules are eager loaded. I'd like mine to be lazy loaded.Tadich
Also it gives me error if I try to load same component or directives twice.Officeholder
Yes I am using eager loading.Officeholder
just for clarification (or maybe a facepalm): from your screenshot, the two chunks using the module seems to be 1 and 2, approx 1mb each. From your diagram chunks 1 and 3 should be using the module. Which one is it?Riess
@Riess names on the screenshot are slightly different. 2.chunk.js should be 3.chunk.js and vice versa. Sorry for the confusion, but I can't easily manupulate the names of chunks.Tadich
E
7

You need to create a SharedAgGridModule:

@NgModule({
  imports: [
    AgGridModule.withComponents([])
  ],
  exports: [
    ContentModule,
    AgGridModule
  ]
})
export class SharedAgGridModule{}

Then you should import this module just for the submodules which uses AgGrid. No need to also import the ContentModule in those submodules, because it is exported in this module

Existence answered 24/1, 2017 at 12:42 Comment(1)
Same as with Santanu's answer, unfortunately :( I am not importing ContentModule into submodules anyway.Tadich
E
0

You can use a SharedModule where you import as well as export the AgGridModule. You have to export the complete module AgGridModule and not just the components you use.

Then you can simply import the SharedModule in your Submodule1 and Submodule3.

Eddaeddana answered 24/1, 2017 at 12:6 Comment(6)
Unfortunately, this leads to the same result. All modules that use SharedModule generate chunks that include the entire ag-grid.Tadich
That means there are services inside the AgGridModule and they need to be added to AppModule.Eddaeddana
But I am not using any of the services from AgGridModule. I only use one of its components.Tadich
You may not be using the services directly. The components maybe using them.Eddaeddana
Looked it up: The module does not expose any services.Tadich
Sorry @AntonPoznyakovskiy, in that case, you have to contact the module author.Eddaeddana
A
0

We facing the same issue.

2 Solutions

  1. Put into ShareModule import and exports it. Sub module import the ShareModule. Basically, ShareModule is without lazy load.
  2. Merge to the same path/module lazy load together.
Amorete answered 6/5, 2017 at 0:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.