webpack学习--tree-shaking剔除无用代码

本文介绍了webpack中的tree-shaking技术,该技术通过分析ES模块,删除未使用的代码以实现优化。起源于rollup.js,tree-shaking在webpack中结合UglifyJSPlugin可以删除未引用的函数。然而,它主要针对模块导入导出的优化,对于隐藏在模块内部的无用代码,仍需要compiler如google的closure compiler进一步处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

tree-shaking,了解一下?
这里写图片描述

1. 例子

在webpack,在pro模式下,UglifyJSPlugin插件可以为我们适当的压缩代码。

具体是怎么压缩的呢?

配置UglifyJSPlugin

const path = require('path');
+ const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
- }
+ },
+ plugins: [
+   new UglifyJSPlugin()
+ ]
};

它会利用ES6模块的静态特性:

  1. 只能作为模块顶层的语句出现,不能出现在 function 里面或是 if 里面。(ECMA-262 15.2)
  2. import 的模块名只能是字符串常量。(ECMA-262 15.2.2)
  3. 不管 import 的语句出现的位置在哪里,在模块初始化的时候所有的 import 都必须已经导入完成。换句话说,ES6 imports are hoisted。(ECMA-262 15.2.1.16.4 - 8.a)
  4. import binding 是 immutable 的,类似 const。比如说你不能 import { a } from ‘./a’ 然后给 a 赋值个其他什么东西。(ECMA-262 15.2.1.16.4 - 12.c.3)

—–引用自尤雨溪

来分析js文件的import和export,把未引用代码(dead code)剔除掉。

这里有两个js文件。

a.js

export {
foo,
bar
};
function foo() {
    return 'foo';
}
funtion bar() {
    return 'bar';
}

main.js

import { foo } from 'a.js';

console.log(foo());

之前a.js里面导出了foo和bar两个函数,因为bar从来没有被引用过,uglify plugin认为它是无用代码,将它删掉。

webpack 使用UglifyJSPlugin处理之后的代码:

// 代表之前的a.js
function (t, n, r) {
        function e() {
            return "foo"
        }

        n.foo = e
    }

这个变化叫做tree-shaking

2. tree-shaking由来

tree-shaking来自于rollup.js,原理相同,就是通过分析静态的ES模块,来剔除未使用代码的。

来看一下如果用rollup来压缩:

(function () {
    'use strict';

    function foo() {
        return 'foo';
    }

    let elem = document.getElementById('output');
    elem.innerHTML = `Output: ${foo()}`;

}());

—–引用自顾轶灵

用rollup压缩更优秀一点,直接把模块里面的函数合并到引用文件里。webpack的压缩还保留有无用的嵌套。

3. 总结

如何评价这个东西呢?

还是有一部分用处的。不过只能解决ES模块相关的导入导出暴露出的无用代码优化问题,实际上,js还有更多无用代码,没有暴露在模块出口入口。这就需要compiler来优化。

google的closure compiler,了解一下?

这里写图片描述

4. 参考:

https://medium.com/@Rich_Harris/tree-shaking-versus-dead-code-elimination-d3765df85c80
https://www.zhihu.com/question/41922432

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值