x)- [ ] bug report -> please search issues before submitting
- [x] feature request
Here's a fairly common scenario: I have an application which has two feature modules that each depend on chart.js. Last time I checked with webpack-bundle-analyzer, angular-cli included the full chart.js library in each of the two feature modules.
The more general case is that feature modules (FM) may want to share another module between another, e.g. I have FM A and FM B and both access an angular module X. However, FM C and FM D do not depend on X. It would be awesome if angular-cli could figure that out from the module declarations/imports and then ensure that module X is loaded the first time either FM A or FM B is loaded. Of course, this would require that X be put in its own bundle/chunk.
I've just stumbled over an article indicating that webpack should support such a scenario with the commonschunk plugin:
https://medium.com/webpack/webpack-bits-getting-the-most-out-of-the-commonschunkplugin-ab389e5f318
The common chunks plugin is actually used. I have also experimented with alternate configurations (various settings, multiple instances, etc.) within the CLI. Unfortunately, the common chunks plugin currently does not analyze the full depth of the child hierarchy. There is this webpack PR that should hopefully improve the situation.
Unless something like a change to common chunks plugin as above PR etc, it's very hard to bring this in.
Currently (loosely speaking) the only sources for chunks are whether vendor chunk is being used or not, and lazy loaded routes.
For the lazy loading, the compiler checks for the loadChildren routes of AppModule and finds which modules those refer to, and repeats the check recursively for all checked modules. It then generate the route information which is later passed to both Webpack for creating chunks, and the router for knowing which imports to call in runtime. It would require a lot of changes to separate both paths, and to also analyze all imports of each module to decide which is used multiple times and could benefit from being a separate bundle.
Without a separate chunk, the only way to import module X once today is to import it in AppModule. This means it doesn't get lazy loaded, and you get to choose between either lazy loading multiple times, or single initial loading.
Hm, I can't comment on the details of integrating this with webpack as I'm far from being an expert in this. Maybe someone like @TheLarkInn could provide some valuable insight as well.
In any case, I though it may be interesting to share the current workaround that I'm using: https://gist.github.com/JohannesRudolph/87bf06aeaa0a94f1129fd0e0216be18f
It's simple and stupid, but at least it ensures very large third party libs (like chart.js) can be reasonably shared between lazy loaded feature modules without duplicate loading. Mind you this comes at the expense of totally evading webpack and any potential benefits we could have from it (e.g. tree-shaking).
The common chunks plugin is already integrated with the CLI. Without additional improvements to the common chunks plugin, there is not much more that can be done currently. Especially if an app has lazy loaded routes with a depth of more than one.
Have you also considered adding the library to the scripts array in .angular-cli.json, with the lazy option set?
I agree that this is a highly desirable feature. We have to wait for https://github.com/webpack/webpack/pull/4255 for now though.
Rollup not working in async router module #7143
@filipesilva
I update the angular/cli to version 1.2.6. The problem seems to be solved, but it introduces a new problem.
The new problem is the async router module bundle itself twice.







I update the code to the repo angular-asyn-routing-test/tree/dev
Looking forward to your reply.
https://github.com/webpack/webpack/pull/4255 has been resolved, is there another blocker?
@mgol I havent had time to look at it further but we've since created a common module that includes all the code shared between lazy routes. Does that not suffice for you case? Can you see any differences when you use the fix in webpack/webpack#4255? If so, you could do a PR.
Consider this situation. A, B, C modules can be lazy loaded at /a, /b, and /c. B and C have a large set of shared dependencies. Most users will start with /a and therefore, it would be best if this large set of dependencies was postponed until /b or /c are accessed. AFAICT, the fact that both B and C share some code means it ends up in the common bundle and therefore gets loaded for /a. It would be preferable if B and C's dependencies were packed into a separate bundle that only got loaded when either /b or /c are accessed. Is this possible with angular-cli, currently?
@filipesilva In a lot of apps, you can't predict what page the user will land on first. The user might also refresh the browser anywhere. If they do this on a route that was lazy-loaded, the it will require common.js which is probably very large. If the code was split into smaller common chunks, it could make a big difference. The app I'm working on has a main/common/lazy-feature ratio of about 1/8/1, so in my case we would benefit a lot from this.
I've been trying to figure this out all day. When it looked like smaller common chunks weren't supported, I tried a hack to force Angular to create a separate chunk for shared module X by defining a lazy-loaded route for it at /x. I figured x.js would get created, which would then be fetched when the user goes to /a, /b, or /x. However, the priority goes to common.js and when I go to /x there isn't an x chunk, instead common.js loads, which still contains the shared module X.
This is more advanced code splitting is now supported with Angular CLI 6.0+.
@clydin That's amazing! I wasn't aware of this! Do you know if this new capability is documented somewhere?
Yes we noticed the same thing after upgrading. All of a sudden we had like
15 bundles more than before. Very cool stuff :-)
Mike Pearson notifications@github.com schrieb am Do. 6. Dez. 2018 um
20:34:
@clydin https://github.com/clydin That's amazing! I wasn't aware of
this! Do you know if this new capability is documented somewhere?—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/angular/angular-cli/issues/6204#issuecomment-445000977,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAH8N062A8A4Q-qr2RR5P6dgNz1cWFuIks5u2XFQgaJpZM4NSrDn
.
@mfp22 I wrote up a description of the new behavior in this comment: https://github.com/angular/angular-cli/issues/10364#issuecomment-382040140
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
Consider this situation. A, B, C modules can be lazy loaded at /a, /b, and /c. B and C have a large set of shared dependencies. Most users will start with /a and therefore, it would be best if this large set of dependencies was postponed until /b or /c are accessed. AFAICT, the fact that both B and C share some code means it ends up in the common bundle and therefore gets loaded for /a. It would be preferable if B and C's dependencies were packed into a separate bundle that only got loaded when either /b or /c are accessed. Is this possible with angular-cli, currently?