tree shaking的原理是什么?

什么是tree-shaking

别名叫摇晃树,最早是由Rollup实现,是一种采用删除不需要的额外代码的方式优化代码体积的技术
tree-shaking会在打包过程中 静态分析 模块之间的导入导出,确定哪些模块导出值没有被使用饼打上标记,并将其删除,从而实现了打包产物的优化。

tree-shaking可以实现的基础

在之前CommonJs、AMD、CMD的模块化方案中,这种导入导出是动态的,难以预测的,因此在打包阶段,是无法分析哪些模块被使用,例如:

if(someTrue){
  require('./bar');
  exports.foo = 'foo';
}

而ES 静态module方案下,模块之间的依赖关系是高度确定的静态的,与运行状态无关,可以进行可靠的静态分析,因此整个依赖树可以被静态地推导出解析语法树,可以做到在编译时候 分析ESM的模块,可以从代码字面量中推断出哪些模块没有被使用,这就是tree-shaking实现的必要条件。

tree-shaking的作用示例

可以看到示例中,bar.js中导出了bar、foo,而只有bar在index.js中使用过,foo从未被用过,经过tree-shaking处理后,foo变量会被视作无用代码删除。

// index.js
import {bar} from './bar';
console.log(bar);

// bar.js
export const bar = 'bar';
export const foo = 'foo';

需要注意的是,export default 导出的是一个对象,「无法通过静态分析判断出一个对象的哪些变量未被使用,所以 tree-shaking 只对使用 export 导出的变量生效」

tree shaking的原理是什么?

看完上面的分析,相信这里你可以很容易的得出题目的答案了:

  • ES6 Module引入进行静态分析,故而编译的时候正确判断到底加载了那些模块
  • 静态分析程序流,判断那些模块和变量未被使用或者引用,进而删除对应代码

配置

mode = ''production" 会自动启动 tree shaking(webpack4以上会默认开启)
package.json中:

  "sideEffects": [
    "@babel/polyfill", 
    "*.css",
    "*.less"
  ],

sideEffects一般用于npm包标记是否有副作用。有副作用则不能去移除,移除了可能会出现bug
例如src目录下有一个extends.js文件

// extends.js
Number.prototype.pad = function(size){
    let result = this + ""
    while(result.length < size){
        result = "0" + result
    }
    return result;
}

在index.js中执行这个模块的内容,为Number原型对象上添加一个pad方法。再执行一个公共css代码模块。

// index.js
import { Button } from "./components"
import "./extends"
import "./global.css"

console.log((8).pad(3));
document.body.appendChild(Button())

extends.js模块和global.css模块都没被打包,而实际上这里是要打包的,

所以就要package.json中关闭副作用

"sideEffects": [
    "./src/extends.js",
    "*.css" 
  ]
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值