• Tree-shaking 文档例子编译后结果和实际不同?


    根据webpack 官方 v.4.43.0 的说法是

    tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块语法的 静态结构 特性,例如 import 和 export。这个术语和概念实际上是由 ES2015 模块打包工具 rollup 普及起来的。

    那总体流程简述如下:

    分析程序流,ES Module 的静态结构,编译时判断到底都加载了哪些模块,标识未被使用的模块和变量,最后启用 uglify 混淆并删除未被使用的代码。

    例子

    笔者传到了 git 仓库里,主要是有两个文件

    // math.js
    export function square(x) {
      return x * x;
    }
    
    export function cube(x) {
      return val * val * val;
    }
    
    // index.js
    import { cube } from './math.js';
    
    function component() {
      // var element = document.createElement("div");
      var element = document.createElement('pre');
      // element.innerHTML = _.join(["Hello", "webpack"], " ");
      element.innerHTML = [
        'Hello webpack!',
        '5 cubed is equal to ' + cube(5)
      ].join('
    
    ');
    
      return element;
    }
    
    document.body.appendChild(component());
    

    官网说法

    官网说道在 mode: development 的模式下编译,会出现 /* unused harmony export square */ 标识

    dist/bundle.js (around lines 90 - 100)

    /* 1 */
    /***/ (function(module, __webpack_exports__, __webpack_require__) {
      'use strict';
      /* unused harmony export square */
      /* harmony export (immutable) */ __webpack_exports__['a'] = cube;
      function square(x) {
        return x * x;
      }
    
      function cube(x) {
        return x * x * x;
      }
    });
    

    最后在 mode: prodution 时启用uglify 压缩混淆代码时,官网给的例子只是说道会去掉没有引入的 square 函数。但能看到引入的 cube 函数。

    显然,现在整个 bundle 都已经被 minify(压缩) 和 mangle(混淆破坏),但是如果仔细观察,则不会看到引入 square 函数,但能看到 cube 函数的混淆破坏版本(function r(e){return eee}n.a=r)

    真实实验结果

    然而我自己的实验结果有些差别!复现的例子笔者已经传到了我的 Git 仓库

    在 mode: development 下编译实际产生的代码是带着 eval 函数的。并且也没有 /* unused harmony export square */ 的标识。

    /***/ "./src/math.js":
    /*!*********************!*
      !*** ./src/math.js ***!
      *********************/
    /*! exports provided: square, cube */
    /***/ (function(module, __webpack_exports__, __webpack_require__) {
    
    "use strict";
    eval("__webpack_require__.r(__webpack_exports__);
    /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "square", function() { return square; });
    /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cube", function() { return cube; });
    // import { toPrimitive } from './util';
    
    function square(x) {
      return x * x;
    }
    
    function cube(x) {
    //   let val = toPrimitive(x);
      return val * val * val;
    }
    
    
    //# sourceURL=webpack:///./src/math.js?");
    
    /***/ }),
    

    并且当 mode 为 prodution 时,编译的结果他不仅去掉了 square,甚至连整个依赖都被直接合并进了主函数里(注意下文的代码里调用依赖函数的地方直接变成了 val * val * val,牛逼啊)。而这又是怎么回事呢?

    .......省略 webpack 基础代码50+行
    ([
      function (e, t, n) {
        "use strict";
        var r;
        n.r(t),
          document.body.appendChild(
            (((r = document.createElement("pre")).innerHTML = [
              "Hello webpack!",
              "5 cubed is equal to " + val * val * val,
            ].join("
    
    ")),
            r)
          );
      },
    ]);
    

    为此我提了一个 issue 去询问,得到答复说是文档太老了有待更新。

    总之我还实验了 util.js -> math.js -> index.js 的三层引用,发现它还是能最后被直接合并入 index 的代码块中,而不是外部的函数。

    我猜测这个 webpack 4.x 的机制,我猜测是打包时直接能把所有依赖的并且是静态 import 的函数直接合并入引入的地方。期待能有大佬来解释

  • 相关阅读:
    i3wm菜单
    开始写博客拉
    xterm配置
    Linux Tips
    docker下运行labview2010
    oracle连接字符串解析
    C# 域登录实现
    解决Winform程序在不同分辨率系统下界面混乱
    FTP设置:FTP隔离用户
    sqlserver 启动不了sqlserver服务,提示特定服务错误代码10048
  • 原文地址:https://www.cnblogs.com/everlose/p/12904579.html
Copyright © 2020-2023  润新知