preface

Generally speaking, when I look at the source code will first go through the code dependency library, so that we will have a rough outline of what the heap of logic in front of us is doing, and then go into the code logic is filling the skeleton, the body of the mind work.

When I looked at the vue. js source code, I opened package.json first.

So I noticed a strange property:

{..."sideEffects": false. }Copy the code

The sideEffects property is not found in any other NPM package, so I went to the official NPM documentation to try to find information about this field.

It turned out to be nothing.

At this point I’ll go to Github and look up the vue.js commit information to see if the person who committed this line of code has given sufficient instructions.

Thanks to vscode’s powerful GitLens plugin, my mouse hovered over it to reveal the submission information for that line of code. Click the #8099 link to get to the current PR situation.> portal

Soon, in the description of this enthusiastic open source contributor, I found this sentence:

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.

This is a feature for those who want to require vue.js source code directly instead of importing it from VUe.js ESM bundles. This configuration allows WebPack to treeshake the packaged code in a more invasive manner.

Treeshake is a configuration related to Webpack.

Tree shaking is a term used to describe removing dead-code from a JavaScript context. It relies on the statically structured features of ES2015 module syntax, such as import and export. This term and concept was actually popularized by the ES2015 module packaging tool rollup. The official webPack 2 version has built-in support for ES2015 modules (also known as Harmony Modules) and unused module detection. The new official version of WebPack 4 extends this detection capability by using the package.json “sideEffects” attribute as a marker to provide compiler with hints as to which files in the project are “pure “. This allows you to safely delete unused portions of the file.

To recast, sideEffects is an element of Webpack’s Treeshake function that allows it to “aggressively” remove dead-code from its code.

So what is dead-code? Here’s a simple example:

The directory structure: demo | – module. Js | – index. Js

// module.js
export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}
Copy the code
// index.js
import { square } from './module'

square(2)
Copy the code

When the entry of our Webpack configuration is index.js, we can see that we didn’t introduce the code function, so

export function cube(x) {
    return x * x * x
}
Copy the code

This code will be called dead-code and will not be referenced anywhere.

However, we can clearly and conclusively judge that it is dead-code by import and export of ES2015, but can it be safely deleted without import? Take a look at the following example from the Button component of Polaris React.

import hoistStatics from 'hoist-non-react-statics';
function Button(_ref) {
  // ...
}
function merge() {
  var _final = {};
  for (
    var _len = arguments.length, objs = new Array(_len), _key = 0;
    _key < _len;
    _key++
  ) {
    objs[_key] = arguments[_key];
  }
  for (var _i = 0, _objs = objs; _i < _objs.length; _i++) {
    var obj = _objs[_i];
    mergeRecursively(_final, obj);
  }
  return _final;
}
function withAppProvider() {
  return function addProvider(WrappedComponent) {
    var WithProvider =
      /*#__PURE__*/
      (function (_React$Component) {
        // ...
        return WithProvider;
      })(Component);
    WithProvider.contextTypes = WrappedComponent.contextTypes
      ? merge(WrappedComponent.contextTypes, polarisAppProviderContextTypes)
      : polarisAppProviderContextTypes;
    var FinalComponent = hoistStatics(WithProvider, WrappedComponent);
    return FinalComponent;
  };
}
var Button$1 = withAppProvider()(Button);
export {
  / /... .
  Button$1};Copy the code

Assuming that our project did not import Button, the code for Button should be dead-code.

But if we look inside the withAppProvider function, we not only call it, but also call its return value as a Button parameter. ** at this point it is difficult to determine whether the deletion of this code has any additional logical effects on the entire code base, i.e. sideEffects. Polyfill code, for example, might modify an object’s prototype, or define or modify some global functions. Usually, such code does not export. This is the scenario webPack had in mind when making Treeshaking.

conclusion

The sideEffects: false attribute tells webpack that I have no sideEffects in this library and that you can leave out non-imported code in aggregating.

See the webpack introduction: treeshaking and sideEffects for a more detailed explanation

At this point, I also know:

  • Treeshaking’s functionality relies on ES2015’s modular syntaximportandexportNo wonder the Vue code is all ES2015 modular.
  • SideEffects is also seriously explored in rollup as a property that specifies a way to reduce the size of a package by removing unwanted code from the package:
    • In 2016, Rollup raised an issue on the tree-shaking function, in which the issue on how to accurately determine whether a piece of code is dead-code caused discussion among many open source authors. And the code that causes sideEffects should not be written: Treeshaking is defeated by Object.defineProperty
    • When I visited the issue, I found that it had been discussed for more than a year. When I saw a comment, I almost burst out laughing:

  • But thanks to a lot of open source gurus, there are good packaging tools, and that’s what the open source community is all about. 😆
  • We finally see the problem by using Uglify and adding comments to functions without sideEffects/*#__PURE__*/To specify its handling, see:Github.com/rollup/roll…. We also added a moduleSideEffects attribute to the internal Treeshaking to specify the corresponding behavior:Rollupjs.org/guide/en/#d…
  • Give vue.js a PR for its package.json to add initiallysideEffects:falseThe man who isSean Larkin, developer of the core WebPack team. Even though vue.js is packaged with rollup, he also mentioned this issue to benefit others who use Webpack. In this way, it is like advertising Webpack with vue.js, a popular open source project. Soon, this PR was merged into master by Utah university (3 May 2018).

Radiating knowledge points

  • treeshaking and sideEffects
  • rollup dangerzone
  • uglify compress options