question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Empty Module Exports Dramatically Affect Bundle Output

See original GitHub issue

Bug report

While integrating TypeScript 3.9 I noticed significant bundle size regressions and confirmed it was triggered by the export * is always retained change by using TS nightlies.

I’ve created a more minimal repro showing that exporting an empty module with no executable code with contents such the one below has significant impact on bundle output.

//# sourceMappingURL=DockPanel.Props.js.map

What is the current behavior?

Adding exports to modules that contain no executable code cause a significant change in bundle output. These images show the effects of adding an export of an empty module with the contents shown above (shown on the left in the images) on bundle output (shown on the right):

Webpack 4:

webpack4

Webpack 5:

webpack5

This also has dramatic effects on split chunk behavior, causing wide swaths of code to move between chunks. I’m hoping this minimal repro is the cause of that behavior, but I’m not sure how to confirm that hypothesis at this point.

If the current behavior is a bug, please provide the steps to reproduce.

Repros

All of these contain a new example called side-effects-empty-module which can be run using the standard example steps. The key line is in module-with-export/index.js which shows dramatic changes to bundle output when commented in and out (effects shown above.)

What is the expected behavior?

I’ve been chatting with @TheLarkInn about this for the past couple of days and agreed we should enter this issue. I don’t think empty module exports should affect the bundle output. (Or at least I would like to understand the reason and mitigate the behavior.)

Other relevant information: webpack version: 4.43.0, 5.0.0-beta.16 Node.js version: 12.16.3 Operating System: Windows 10 Additional tools:

Terms: bundle size regression, ts3.9, typescript 3.9, 3.9.2

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:35 (17 by maintainers)

github_iconTop GitHub Comments

3reactions
amalitskycommented, Jul 31, 2020

Folks, is fix in question available or planned for webpack 4.x? Looks like in 4.x we can’t use experiments: { outputModule: true } option.

And being angular app we can’t go for typescript 4.x version just yet.

Any course of action you could recommend? Thanks

Also huge thanks to topic starter @JasonGore, it was quite a relief to find this issue after spending many hours on debugging. 🎉

2reactions
sokracommented, May 19, 2020

For webpack 5 I managed to fully optimize the case in your repro. Even with the offending export * from "empty" the result is now: (()=>{"use strict";console.log("a","smallVar")})();

For completeness I add problem 3:

  1. Modules with unknown / dynamic provided exports are not considered for module concatenating. I fixed that by using the used exports as replacement for these information. This works as long the used exports are not dynamic or point to dynamic exports. So reexporting a CommonJs module is fine as long you don’t reference (possible) exports from it. Together with the side-effect optimization reexported empty modules can be omitted from the bundle.

btw with

output: {
	module: true
},
experiments: {
	outputModule: true
}

your repro will lead to this output: console.log("a","smallVar");

Read more comments on GitHub >

github_iconTop Results From Across the Web

Export a webpack bundle / prepend module.exports? Avoid ...
I'm trying to require my bundle.js into my Node server, but apparently the webpack bundle is missing a module.exports = before all of...
Read more >
rollup.js
You can export an array from your config file to build bundles from several unrelated inputs at once, even in watch mode. To...
Read more >
API - ESBuild
When bundling is enabled the default output format is set to cjs , which stands for CommonJS (the module format used by node)....
Read more >
Understanding Modules and Import and Export Statements ...
A module exports to provide code and imports to use other code. Modules are useful because they allow developers to reuse code, they...
Read more >
How CommonJS is making your bundles larger - web.dev
With CommonJS you can define modules, export functionality from them, and import them ... How does CommonJS affect your final bundle size?
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found