Skip to content
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

fix(bazel): disable treeshaking when generating FESM and UMD bundles #32069

Closed
wants to merge 2 commits into from
Closed

fix(bazel): disable treeshaking when generating FESM and UMD bundles #32069

wants to merge 2 commits into from

Conversation

alan-agius4
Copy link
Contributor

@alan-agius4 alan-agius4 commented Aug 9, 2019

There has been a regression where enabling rollup treeshaking causes errors during runtime because it will drop const access which will always evaluate to true or false. However, such const in @angular/core cannot be dropped because their value is changed when NGCC is run on @angular/core

VE

const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__PRE_R3__;

Ivy (After NGCC)

const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__POST_R3__;

FESM2015

load(path) {
	/** @type {?} */
	const legacyOfflineMode = this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}

ESM2015

 load(path) {
	/** @type {?} */
	const legacyOfflineMode = !ivyEnabled && this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}

From the above we can see that ivyEnabled is being treeshaken away when generating the FESM bundle which is causing runtime errors such as Cannot find module './lazy/lazy.module.ngfactory' since in Ivy we will always load the factories.

@alan-agius4 alan-agius4 requested review from a team as code owners August 9, 2019 07:50
@alan-agius4 alan-agius4 added target: patch This PR is targeted for the next patch release PR action: time-zone area: bazel Issues related to the published `@angular/bazel` build rules labels Aug 9, 2019
@ngbot ngbot bot added this to the needsTriage milestone Aug 9, 2019
@alan-agius4 alan-agius4 added effort1: hours action: review The PR is still awaiting reviews from at least one requested reviewer labels Aug 9, 2019
There has been a regression where enabling rollup treeshaking causes errors during runtime because it will drop const access which will always evaluate to true or false. However, such `const` in `@angular/core` cannot be dropped because their value is changed when NGCC is run on `@angular/core`

VE
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__PRE_R3__;
```

Ivy (After NGCC)
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__POST_R3__;
```

FESM2015
```
load(path) {
	/** @type {?} */
	const legacyOfflineMode = this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

ESM2015
```
 load(path) {
	/** @type {?} */
	const legacyOfflineMode = !ivyEnabled && this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

From the above we can see that `ivyEnabled ` is being treeshaken away when generating the FESM bundle which is causing runtime errors such as `Cannot find module './lazy/lazy.module.ngfactory'` since in Ivy we will always load the factories.
@@ -111,6 +111,41 @@ Hello
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: with this approach, all methods from tslib will be inlined.

I know that @alexeagle had in mind to put tslib as a peerDepedency instead of it being a direct dependency, which eventually would make tslib helpers as externals for UMD bundles as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could tell rollup that tslib is external right? I think that's the mechanism that would prevent it being bundled in; then we'd need to fix any package.json files to warn users using the peerDep mechanism. Do you plan to do that as a follow-up?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we could for umd, we are explicitly stating the we should include tslib

I would like to follow this up and take on TOOL-836, though would like to confirm that @IgorMinar is onboard, if my memory serves me well, he had some concerns not to include tslib as a direct dependency in version 6.

Copy link
Member

@devversion devversion Mar 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just came across this. tslib is now a peer dependency for all Angular packages. Though we still bundle tslib into the UMD bundles. This seems to cause unnecessary bloat when multiple UMD bundles are loaded.

Ideally we'd just not bundle tslib into it, and require consumers to load tslib before. I think we don't do this right now because there is no UMD bundle for tslib.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth looking into this again. Potentially we could help tslib with providing an UMD version so that we can move forward with this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with not inlining tslib is that it be a breaking change because we will breaks users who uses umds.

See also: #32167 (review)

What is the problem you are seeing? Or is it just a size matter?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a matter of size. It makes sense that we continue bundling it for backwards compatibility. Though, I'm wondering if we could/should revisit this in the future. It seems not ideal to include tslib into the bundles multiple times, given that rxjs is external too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally the fact that tree-shaking had to be disabled here, doesn't make it better. As you already stated, it means that the whole tslib library is included even if only parts are needed.

@alan-agius4
Copy link
Contributor Author

Note: this regressions is causing Ivy E2E tests in the CLI to be break.

@vladimiry
Copy link

Was going to file the issue but fortunately found this PR. I had to roll back to 8.2.0 due to this issue since NgModuleFactoryLoader.load got broken in ivy mode.

@vladimiry
Copy link

And, well, it's not Bazel-only specific since this code stopped working with direct @ngtools/webpack.AngularCompilerPlugin use for compiling (because legacyOfflineMode always resolves to true with 8.2.1).

@alan-agius4
Copy link
Contributor Author

@vladimiry, this bazel rule is to publish the Angular framework.

The bug itself lies in the shipped @angular/core package as certain code which is required at runtime was removed..

@vladimiry
Copy link

vladimiry commented Aug 9, 2019

Thanks for the clarification, then there should be another @angular/core-related issue/PR I've not located yet. I got to this PR using legacyOfflineMode as a search keyword since I debugged the stuff to this stage.

@alan-agius4
Copy link
Contributor Author

Not quite, since this is a bundling issue, there are no code changes required in @angular/core.

@vladimiry
Copy link

vladimiry commented Aug 9, 2019

Do I get it right that 8.2.1 published on npm repository is going to be marked as deprecated to reduce probability of 8.2.1 use by the developers? Since there is no ivyEnabled flag in published pre-compiled fesm* folders and there is no way to get it back for the already published version.

@alan-agius4
Copy link
Contributor Author

I think the preferred approach would be to cut another release versioned 8.2.2

@vladimiry
Copy link

vladimiry commented Aug 9, 2019

My point is that deprecating 8.2.1 could reduce potential damage. Anyway looking forward to trying 8.2.2.

vladimiry added a commit to vladimiry/ElectronMail that referenced this pull request Aug 9, 2019
@vikerman
Copy link
Contributor

vikerman commented Aug 9, 2019

FYI - @gregmagolan

@gregmagolan gregmagolan self-requested a review August 9, 2019 18:37
Copy link
Contributor

@gregmagolan gregmagolan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Unfortunate that all tree-shaking has to be disabled but doesn't look like rollup has fine grained options other than

--no-treeshake              Disable tree-shaking optimisations
--no-treeshake.annotations  Ignore pure call annotations
--no-treeshake.propertyReadSideEffects Ignore property access side-effects

@alan-agius4
Copy link
Contributor Author

@gregmagolan, yeah there doesn't seem to be an option to disable such treeshaking.

@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Aug 9, 2019
Copy link
Member

@josephperrott josephperrott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for devinfra

kara pushed a commit that referenced this pull request Aug 9, 2019
…32069)

There has been a regression where enabling rollup treeshaking causes errors during runtime because it will drop const access which will always evaluate to true or false. However, such `const` in `@angular/core` cannot be dropped because their value is changed when NGCC is run on `@angular/core`

VE
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__PRE_R3__;
```

Ivy (After NGCC)
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__POST_R3__;
```

FESM2015
```
load(path) {
	/** @type {?} */
	const legacyOfflineMode = this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

ESM2015
```
 load(path) {
	/** @type {?} */
	const legacyOfflineMode = !ivyEnabled && this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

From the above we can see that `ivyEnabled ` is being treeshaken away when generating the FESM bundle which is causing runtime errors such as `Cannot find module './lazy/lazy.module.ngfactory'` since in Ivy we will always load the factories.

PR Close #32069
kara pushed a commit that referenced this pull request Aug 9, 2019
@gkalpak gkalpak added the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Aug 9, 2019
@kara kara removed the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Aug 9, 2019
@kara kara closed this in 4f37487 Aug 9, 2019
@kara
Copy link
Contributor

kara commented Aug 9, 2019

@alan-agius4 Since the review missed the merge by ~1 min, it was merged without the typo fix. Would you mind addressing the feedback in a follow-up? #32069 (comment)

@alan-agius4 alan-agius4 deleted the rollup-tree-shaking branch August 10, 2019 05:48
@alan-agius4
Copy link
Contributor Author

@kara sure!

pkozlowski-opensource pushed a commit to pkozlowski-opensource/angular that referenced this pull request Aug 12, 2019
…ngular#32069)

There has been a regression where enabling rollup treeshaking causes errors during runtime because it will drop const access which will always evaluate to true or false. However, such `const` in `@angular/core` cannot be dropped because their value is changed when NGCC is run on `@angular/core`

VE
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__PRE_R3__;
```

Ivy (After NGCC)
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__POST_R3__;
```

FESM2015
```
load(path) {
	/** @type {?} */
	const legacyOfflineMode = this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

ESM2015
```
 load(path) {
	/** @type {?} */
	const legacyOfflineMode = !ivyEnabled && this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

From the above we can see that `ivyEnabled ` is being treeshaken away when generating the FESM bundle which is causing runtime errors such as `Cannot find module './lazy/lazy.module.ngfactory'` since in Ivy we will always load the factories.

PR Close angular#32069
pkozlowski-opensource pushed a commit to pkozlowski-opensource/angular that referenced this pull request Aug 12, 2019
sabeersulaiman pushed a commit to sabeersulaiman/angular that referenced this pull request Sep 6, 2019
…ngular#32069)

There has been a regression where enabling rollup treeshaking causes errors during runtime because it will drop const access which will always evaluate to true or false. However, such `const` in `@angular/core` cannot be dropped because their value is changed when NGCC is run on `@angular/core`

VE
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__PRE_R3__;
```

Ivy (After NGCC)
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__POST_R3__;
```

FESM2015
```
load(path) {
	/** @type {?} */
	const legacyOfflineMode = this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

ESM2015
```
 load(path) {
	/** @type {?} */
	const legacyOfflineMode = !ivyEnabled && this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

From the above we can see that `ivyEnabled ` is being treeshaken away when generating the FESM bundle which is causing runtime errors such as `Cannot find module './lazy/lazy.module.ngfactory'` since in Ivy we will always load the factories.

PR Close angular#32069
sabeersulaiman pushed a commit to sabeersulaiman/angular that referenced this pull request Sep 6, 2019
@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 Sep 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: bazel Issues related to the published `@angular/bazel` build rules cla: yes effort1: hours target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants