This is the fourth day of my participation in Gwen Challenge

Lynne, a front-end development engineer who can cry, love and laugh forever. In the Internet wave, love life and technology.

preface

Webpack + Uglify tree shaking I said I don’t dov hahaha…

Not long talk about a lot of details of the source code, want to let me 5 minutes to understand the source code that is impossible, mainly about the implementation principle, involving specific configuration items thinking. Tree-shaking, as we’ll look at it, is only part of the inherent functionality of packaging and compression tools, and the power tools themselves need to be understood a little bit.

Configured to use

As we mentioned earlier, the WebPack package only marks import and export statements, and Uglify removes invalid code when it is compressed.

I covered the details of plug-in configuration for WebPack in the previous article. In addition, since the source code must conform to the ES6 module specification, the configuration file needs to be modified to specify that Babel does not convert ES6 modules into CommonJS modules when processing JS files. To set the babel-preset- ES2015 modules to fasle for.babelrc, ES6 modules will not be processed.

// .babelrc
{
    "presets": [
        [
          "es2015",
          {"modules": false}
        ]
    ]
}
Copy the code

You can still tree shaking in Webpack 3 and 4 without adding the.babelrc file.

So how does Webpack tag code, and how does Uglify recognize and tree-shaking webPack tag code?

Tree-shaking implementation flow

Webpack markup code

In general, Webpack marks the code, mainly for import & export statements, as three classes:

  • All imports are marked as/* harmony import */
  • All used exports are marked as/* harmony export ([type]) */, including[type]Binding, immutable, and so on
  • The unused export is marked as/* unused harmony export [FuncName] */, including[FuncName]Is the method name of export

UglifyJS compression and clearance method

UglifyJS is a set of PARSER, minifier, compressor, and beautifier tools (Parser, minifier, Compressor or Beautifier Toolkit). For details, please refer to UglifyJS Chinese manual

If you don’t want to browse through such a long document, take a look at my neat, straight-forward tree-shaking summary.

  • Dead_code — Remove unreferenced code // Doesn’t look familiar! Useless code!
  • Drop_debugger — Removes the debugger
  • Unused – Kills functions and variables that are not referenced. (A simple direct assignment to a variable is not referenced unless “keep_assign” is set.)
  • Toplevel – Kills functions (“funcs”) and/or variables (“vars”) that are not referenced in the top-level scope (default is false, true kills all function variables)
  • Warnings – display warnings when deleting code that is not useful // nice
  • Pure_getters — The default is false. If you pass true, UglifyJS assumes that references to object properties (such as foo.bar or foo[“bar”]) have no function side effects.
  • Pure_funcs — null by default. You can pass in an array of names, and UglifyJS will assume that these functions have no side effects.
plugins: [ new UglifyJSPlugin({ uglifyOptions: { compress: Pure_funcs: [' math.floor ']}}})], {// This function is considered to have no function side effects and the whole declaration is discarded.Copy the code

If the name is redefined in scope, it will not be checked again. For example, var q = math.floor (a/b), if the variable q is not referenced, UglifyJS will kill it, but math.floor (a/b) will be kept, and no one knows what it does.

  • Side_effects — Default true. Pass false to disable discarding pure functions. If a function is called with a slash before it is called@PURE/ or /#PURE/ comment, the function will be marked as pure. For example, /@PURE/foo();

In fact, with so many compression configurations, it is possible to remove useless markup code using only the UglifyJS default configuration for tree-shaking.

UglifyjsWebpackPlugin

The latest version of webpack5 retains the built-in Uglifyjs plugin, UglifyjsWebpackPlugin.

The basic usage is also simpler:

// webpack.config.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [new UglifyJsPlugin()],
  },
};
Copy the code

babili – BabelMinify

Babili, renamed BabelMinify, is a code compression tool based on Babel, which already understands the new syntax through our parser Babylon and integrates UglifyJS compression into Babili. In essence, it does the same thing as UglifyJS, but with babili you don’t have to translate it, you compress it, making the code smaller (see conclusion).

There are two ways to use Babili to replace Uglify: babili plug-in and babel-loader default.

Babili plug-in

Instead of uglify, use Babili instead of Uglify. There is no need for babel-loader:

plugins: [
  new BabiliPlugin()
]
Copy the code

Babel – loader preset

Babel Minify is best suited for the latest browsers (with full ES6+ support) and can also be used with the usual Babel ES2015 presets to compile code down first, as explained at the end of the official documentation.

Using Babel-Loader in webpack and then introducing Minify as a preset will run faster than using the BabelMinifyWebpackPlugin directly (covered next). Because babel-Minify processes smaller files.

Babelrc is configured as follows:

{
  "presets": ["es2015"],
  "env": {
    "production": {
      "presets": ["minify"]
    }
  }
}
Copy the code

BabelMinifyWebpackPlugin

BabelMinify – BabelMinify webpackplugin is a built-in plugin in webpack5.

// webpack.config.js const MinifyPlugin = require("babel-minify-webpack-plugin"); module.exports = { entry: //... , output: //... , plugins: [ new MinifyPlugin(minifyOpts, pluginOpts) ] }Copy the code

UglifyjsWebpackPlugin VS BabelMinifyWebpackPlugin

Compared with the latest version of Webpack in the production environment, UglifyjsWebpackPlugin is more advantageous in terms of packaging time in the experiment, but BabelMinifyWebpackPlugin is better in terms of packaging volume.

The performance comparison

Contestant no. 1 UglifyjsWebpackPlugin

Contestant No. 2 BabelMinifyWebpackPlugin

conclusion

Today we are talking about webPack packaging + UglifyJS compression implementation tree-shaking, and from Babel translation + UglifyJS compression optimization to directly using BabelMinify implementation.

Webpack + Terser Compression tree-shaking

The resources

  • UglifyJS Chinese manual