Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What Does Webpack 4 Expect From A Package With sideEffects: false

Webpack 4 has added a new feature: it now supports a sideEffects flag in the package.json of the modules it is bundling.

From Webpack 4: released today

Over the past 30 days we have worked closely with each of the frameworks to ensure that they are ready to support webpack 4 in their respective cli’s etc. Even popular library’s like lodash-es, RxJS are supporting the sideEffects flag, so by using their latest version you will see instant bundle size decreases out of the box.

From Webpack docs

The "sideEffects": false flag in big-module's package.json indicates that the package's modules have no side effects (on evaluation) and only expose exports. This allows tools like webpack to optimize re-exports.

Whilst the second link shows the results of using the flag, it doesn't clearly explain what constitutes a side-effect. ES6 includes the concept of side-effects for modules as outlined here, but how does this relate to what Webpack considers side-effects.

In the context of the sideEffects flag, what does a module need to avoid to use sideEffects:false without issues, or conversly, what does a module need to do in order to use sideEffects:false without issues.

For completeness, despite @SeanLarkin's solid answer below, I would love to get clarification on the following:

  1. Obviously side-effects means something particular in fp and would include logging (console or elsewhere) and the throwing of errors. I'm assuming in this context these are perfectly acceptable?

  2. Can a module contain circular references and still use sideEffects: false?

  3. Is there any way to verify or that a module is able to verify that a module can sideEffects: false beyond trying to track down errors caused by its misuse?

  4. Are there any other factors that would prevent a module from being able to use sideEffects: false?

like image 306
Undistraction Avatar asked Mar 07 '18 20:03

Undistraction


People also ask

What is a side effect webpack?

A "side effect" is defined as code that performs a special behavior when imported, other than exposing one or more exports. An example of this are polyfills, which affect the global scope and usually do not provide an export.

What is webpack and what problem does it solve?

Webpack applies automatic transformations on your working files to make them into production files that are more useful for your end user. Those transformed files are copies, and they go to a different folder, so the original files are never modified on this process and stuff keeps tidy.

What is webpack in package json?

Webpack is used to compile JavaScript modules. Once installed, you can interact with webpack either from its CLI or API. If you're still new to webpack, please read through the core concepts and this comparison to learn why you might use it over the other tools that are out in the community.

What is tree shaking in webpack?

Tree shaking, also known as dead code elimination, is the practice of removing unused code in your production build. It's important to ship as little code to your end-users as possible. By statically analyzing our source code, we can determine what's not being used and exclude it from our final bundle.


1 Answers

Sean from the webpack Team! I'll do my best in lieu of our documentation still in progress to answer your question here!

According to the ECMA Module Spec (I'm not going to try and find the link so you'll have to trust me here because it's buried),

whenever a module re-exports all exports, (regardless if used or unused) they need to be evaluated and executed in case one of those exports created a side-effect with another.

For example I've created a small scenario with a photo to better visualize the case:

In this photo we see three modules imported into a single file. The imported modules are then re-exported from that module:

Example of No Side Effects from Re-exported Modules

You can see here that none of the re-exports are effected by each other, therefore (if webpack was given a signal), we could omit exports b and c from even being traced or used (size and build time performance benefits).

enter image description here

However in this case, we see that exports c is "effected" by local state changes because it is reassigned to the summation of b and a. Therefore, (which is why the spec calls for this), we would need to include both b and a and any of its dependencies into the bundle.

We chose "sideEffects: false" as a way to save on both compile time and build size because this allows us to instantly prune (explicitly) exports that developers/library authors know are side-effect free (at the expense of a property in a package.json, or 2-3 more lines of config).

Although technically this example is very primitive, when you start dealing with Frameworks or Libraries that re-export a bunch of modules up to a higher level for Developer Experience (Three.js, Angular, lodash-es, etc), then performance gains are significant when (if they are sideEffect free module exports) you flag them in this manner.

Additional Clarifications:

  1. Obviously side-effects means something particular in fp and would include logging (console or elsewhere) and the throwing of errors. I'm assuming in this context these are perfectly acceptable?

In the case that this is trying to solve, yes. As long as effects created against module exports aren't effected by others that would cause pruning to not be acceptable.

  1. Can a module contain circular references and still use sideEffects: false?

It should, in theory.

  1. Is there any way to verify or that a module is able to use sideEffects: false beyond trying to track down errors caused by its misuse?

Not that I know of, however this would be a great tool.

  1. Are there any other factors that would prevent a module from being able to use sideEffects: false?

If the property is not in package.json or defined in module.rules, or mode: production is not set (which leverages the optimization).

like image 52
Sean Larkin Avatar answered Oct 05 '22 04:10

Sean Larkin