Skip to content

Javascript that should be in lazy loaded chunk is in the main chunk #19527

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 of 15 tasks
csbenjamin opened this issue Dec 2, 2020 · 8 comments
Closed
1 of 15 tasks

Comments

@csbenjamin
Copy link

🐞 Bug report

Command (mark with an x)

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • extract-i18n
  • run
  • config
  • help
  • version
  • doc

Is this a regression?

I am not sure

Description

If we create a new app with Router generated by ng new, add @angular/material to the project and we import MatListModule into the main NgModule without using it, @angular/forms will not be in the main bundle. If we add a lazy loaded route, and in that NgModule we import MatInputModule, use MatInput in the lazy component and remove MatListModule from the main module, than the @angular/forms goes into the bundle of the lazy loaded module. Everything works great so far. Now, import MatListModule again in the main NgModule. The @angular/forms now goes to the main bundle.

🔬 Minimal Reproduction

git clone https://github.com/csbenjamin/issue-with-tree-shake
cd issue-with-tree-shake
npm install
ng buil --prod

you will see that @angular/forms goes to the main bundle, and it shouldn't.

🌍 Your Environment


Angular CLI: 10.1.7
Node: 14.8.0
OS: linux x64

Angular: 10.1.6
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1001.7
@angular-devkit/build-angular   0.1001.7
@angular-devkit/core            10.1.7
@angular-devkit/schematics      10.1.7
@angular/cdk                    10.2.7
@angular/cli                    10.1.7
@angular/material               10.2.7
@schematics/angular             10.1.7
@schematics/update              0.1001.7
rxjs                            6.6.3
typescript                      4.0.5
@alan-agius4
Copy link
Collaborator

Duplicate of angular/angular#37576 (comment)

@alan-agius4 alan-agius4 marked this as a duplicate of angular/angular#37576 Dec 2, 2020
@csbenjamin
Copy link
Author

@alan-agius4 Elaborating the example we gave in that comment, assume we have

shared.js

export function foo() { }

export function bar() { }

export function buz() { }

lib.js

import { foo, buz } from './shared';
export function faa() { }

export function ber() { foo(); buz() }

main.js

import { faa } from './lib';
faa();

lazy.js

import { bar, buz } from './shared';
bar();
buz();

In this case, will the shared.js also be imported in the main chunk? Because this is exactly my use case.

@alan-agius4
Copy link
Collaborator

Yeah indeed that is the case.

@alan-agius4
Copy link
Collaborator

You can use the commonChunk option to extract the common dependencies and generate a separate bundle containing code used across multiple chunks.

See: https://angular.io/cli/build

@csbenjamin
Copy link
Author

@alan-agius4 commonChunk is default to true.

My use case is that I am using MatListModule in the main NgModule. MatListModule have the List part, that does not depend on @angular/forms and ListSelect part, that does depend on @angular/forms. I am using just the List part (mat-nav-list) in the main NgModule and I am using MatInputModule in a lazy loaded NgModule. So, @angular/forms is getting imported in the main NgModule. If I stop using MatListModule in the main module, than @angular/forms goes to the lazy loaded chunk.

So, I am going to open an issue in the angular/material repository asking for spliting the List and ListSelect parts of MatListModule into two separated NgModule, so we can use mat-nav-list without import @angular/form.

For now, I am going to stop using mat-nav-list in my main component.

Thanks for your attention.

@alan-agius4
Copy link
Collaborator

So, I am going to open an issue in the angular/material repository asking for spliting the List and ListSelect parts of MatListModule into two separated NgModule, so we can use mat-nav-list without import @angular/form.

Creating a new ngModule will not cause a different behaviour because the problem here is at JavaScript module level where contents of the same module cannot be split into multiple chunks by Webpack.

The unused dependency on @angular/forms in main.js which is being pulled transitively via from @angular/material/list will be removed at a later stage by terser at which point the chunk structure is already created.

An alternatively to this would be to have different entry-point or using ESM bundles instead of FESM (#13635).

@csbenjamin
Copy link
Author

The unused dependency on @angular/forms in main.js which is being pulled transitively via from @angular/material/list will be removed at a later stage by terser at which point the chunk structure is already created.

But as you can see in my repository reproduction, @angular/forms is not being removed from main.js. What am I missing here?

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jan 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants