
本文将探讨tree-shaking在当下的现状,以及研究为什么tree-shaking依旧举步维艰的原因,最终总结当下能提高tree-shaking效果的一些手段。
Tree-Shaking这个名词,很多前端coder已经耳熟能详了,它代表的大意就是删除没用到的代码。这样的功能对于构建大型应用时是非常好的,因为日常开发经常需要引用各种库。但大多时候仅仅使用了这些库的某些部分,并非需要全部,此时Tree-Shaking如果能帮助我们删除掉没有使用的代码,将会大大缩减打包后的代码量。
Tree-Shaking在前端界由 rollup首先提出并实现,后续 webpack在2.x版本也借助于 UglifyJS实现了。自那以后,在各类讨论优化打包的文章中,都能看到Tree-Shaking的身影。
许多开发者看到就很开心,以为自己引用的elementUI、antd 等库终于可以删掉一大半了。然而理想是丰满的,现实是骨干的。升级之后,项目的压缩包并没有什么明显变化。
我也遇到了这样的问题,前段时间,需要开发个组件库。我非常纳闷我开发的组件库在打包后,为什么引用者通过ES6引用,最终依旧会把组件库中没有使用过的组件引入进来。
下面跟大家分享下,我在Tree-Shaking上的摸索历程。
这里我不多冗余阐述,直接贴百度外卖前端的一篇文章: Tree-Shaking性能优化实践 - 原理篇。
如果懒得看文章,可以看下如下总结:
ES6的模块引入是静态分析的,故而可以在编译时正确判断到底加载了什么代码。
分析程序流,判断哪些变量未被使用、引用,进而删除此代码。
很好,原理非常完美,那为什么我们的代码又删不掉呢?
了解过函数式编程的同学对副作用这词肯定不陌生。它大致可以理解成:一个函数会、或者可能会对函数外部变量产生影响的行为。
举个例子,比如这个函数:
function go (url) {
window.location.href = url
}
这个函数修改了全局变量location,甚至还让浏览器发生了跳转,这就是一个有副作用的函数。
现在我们了解了副作用了,但是细想来,我写的组件库也没有什么副作用啊,我每一个组件都是一个类,简化一下,如下所示:
// componetns.js
export class Person {
constructor ({ name, age, sex }) {
this.className = 'Person'
this.name = name
this.age = age
this.sex = sex
}
getName () {
return this.name
}
}
export class Apple {
constructor ({ model }) {
this.className = 'Apple'
this.model = model
}
getModel () {
return this.model
}
} // main.js
import { Apple } from './components'
const appleModel = new Apple({
model: 'IphoneX'
}).getModel()
console.log(appleModel)
用rolluprepl尝试了下tree-shaking,也确实删掉了Person, 传送门
可是为什么当我通过webpack打包组件库,再被他人引入时,却没办法消除未使用代码呢?
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-59797-1.html
哈
这是赤裸裸的侵略