The original link

Webpack V4 started adding a sideEffects feature by adding sideEffects to package.json: False declares whether the package module contains sideEffects, giving Tree-Shaking more room for optimization.

Here’s a picture to get a feel for it:

Note: the V4 beta version is calledpure moduleLater it was changedsideEffects

Based on our understanding of sideEffects in FP, we can assume that as long as we make sure that the modules in the current package do not contain side effects, and then label the packages released to NPM as sideEffects: False, we can provide a better packaging experience for the user. The idea is that WebPack automatically prunes unnecessary imports by converting packages marked side-effects-free from import {a} from xx to import {a} from ‘xx/a’. This function is the same as babel-plugin-import.

Happily, I added this configuration to several of my libraries (making sure there were no side effects).

Until I saw @sean Larkin submit a pr: chore(package.json) to vue a few months ago: Add sideEffects: False: field in package.json = “field”; false: field in package.json; False is true. The e truth is THAT I was slapped in the face because IU quickly merged the PR. This led me to be afraid to add this configuration to mobx because I had no idea what webPack’s sideEffects meant.

Until two days ago, someone mentioned an issue to Mobx-utils, saying that I could add this configuration to help tree shaking. In doubt, I remembered the PR of Vue and looked it up again, and found that someone had asked me the same question under PR:

Hy Sean!

Could you please specify what you mean by “vue’s original source files”?

I looked at the index.js file in the src/core folder and to my knowledge there are plenty sideeffects that would be prune away by tree shaking. (e.g Object.defineProperty)

I hope you can help me understand how this works.

Here’s what Sean’s original PR said:

This PR adds the "sideEffects": false property in vue’s package.json file. This allow’s webpack (for those who want to opt-in to requiring vue’s original source files (instead of the flattened esm bundles) and want to remove flow type through a babel-transform, then this will allow webpack to aggressively ignore and treeshake unused exports throughout the module system.

Sean’s point is that WebPack can help you make tree shaking better when you import vue source files as needed instead of packaged bundles. For example, you can refer to a module in vue by importing vue from ‘vue/ SRC /core’.

Sean then says that this side effect is not that side effect (in fp), and then gives his answer on stackoverflow to explain sideEffects. The main idea is:

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

Every time a module reexports all exports (whether or not they will be used) that need to be evaluated and executed, one export has a side effect on the other exports.

To be honest, I still don’t understand. What -does-webpack-4-expect-from-a-package-with-sideeffects-false

After reading the official document and official example, we only understand the bundle changes after having sideEffects, but still can’t explain the difference between Webpack sideEffects and FP sideEffects. It also doesn’t explain why vue can still configure sideEffects: false when there are many sideEffects.

Chairman MAO taught us: self-reliance, adequate food and clothing.

Tree Shaking and side effects

I won’t go into the background of Tree Shaking but I think many people know it, Webpack’s Tree Shaking allows you to mark unused exported members as unused and not export them in modules that re-export them. It’s a mouthful to say. Look at the code:

// a.js
export function a() {}
// b.js
export function b(){}
// package/index.js
import a from './a'
import b from './b'
export { a, b }
// app.js
import {a} from 'package'
console.log(a)
Copy the code

When we have app.js as an entry, the code will look like this after tree shaking:

// a.js
export function a() {}
Function b(){}
function b() {}
// package/index.js does not export module B anymore
import a from './a'
import b from './b'
export { a }
// app.js
import {a} from 'package'
console.log(a)
Copy the code

With webpack’s Scope collieries and Uglify, the traces of module B will be completely erased.

But if module B adds some side effect, such as a simple log:

// b.js
export function b(v) { reutrn v }
console.log(b(1))
Copy the code

After webpack, you will find that the b module content becomes:

// b.js
console.log(function (v){return v}(1))
Copy the code

Although the b module export is ignored, the side effect code is retained. Due to the current side-effects of all the weird operations transformer can introduce (reference: your tree-shaking is not very useful), many times we find that even with Tree Shaking our bundle size does not decrease significantly. What we normally expect is that since module B is not in use, all of its code should not be introduced.

This is where sideEffects come into play: if we introduce a package/module that is marked sideEffects: false, the module/package will be removed as long as it is not referenced, regardless of whether it actually has sideEffects or not. For example, the Mox-React-devtool can be used like this:

import DevTools from 'mobx-react-devtools';

class MyApp extends React.Component {
  render() {
    return (
      <div>. { process.env.NODE_ENV === 'production' ? null :<DevTools /> }
      </div>); }}Copy the code

This is a very common import scene on demand, however, without sideEffects: With false, even if NODE_ENV is set to production, the package still contains the Mox-React-devTools package, even though we don’t use its exported members. – Mox-React-devtools will still be imported, however, as there are “possible” side effects. But when we add sideEffects False, tree Shaking can safely remove it completely from the bundle.

Use scenarios for sideEffects

As mentioned above, it is often difficult to ensure that the packages we publish to NPM contain side effects (such as the code’s pot or transformer’s pot), but we can generally ensure that the packages have effects on objects outside of the package, such as modifying properties on Windows, Whether native object methods are copied, etc. If we can guarantee this, we can actually see if the entire package can set sideEffects: false, and it doesn’t really matter if there are sideEffects, which is acceptable for webpack. This explains why we can add sideEffects: false to vue, which is itself full of sideEffects.

So sideEffects in WebPack: “False” does not mean that the module has no side effects, but just to tell webpack when shaking the tree: the package was designed to have no side effects, even if it does have side effects after it is finished, you can safely shake the tree as if it has no side effects. .

That said, as long as your bag is not being used for polyfill or shim, feel free to add sideEffects: false!