深入研究webpack之Tree Shaking相关属性sideEffects用处
Tree Shaking我原来也只是了解,这次碰巧深入研究了下,就写个博客记录一下,网上有很多讲Tree Shaking的,我写的这篇跟他们侧重点不一样
Tree Shaking相关的基础知识
1 webpack会从入口文件开始不断的获取你的依赖,就像一颗树一样从根节点开始不断往下延伸,只有被依赖的文件才会加入树,注意这不叫Tree Shaking,Tree Shaking是指依赖的文件只需要的一部分,则把不需要的部分代码摇掉
2 Tree Shaking只能识别es6语法,这点很关键(注意去掉polyfill的模块降级),但是webpack不支持es6打包,也就是说你用import写的代码可以被Tree Shaking,但是你npm别人的库,如果别人不是es写法,那么无法Tree Shaking。比如lodash和lodash-es,后者是es的导入写法,代码就可以被压缩。
3 Tree Shaking原来是用uglifyjs来做压缩的,现在由于现在不维护uglify-es了(uglify-es is no longer maintained ),现在改用terser了,据说是uglify的一个分支。(对我们使用来说其实没什么感觉,只是了解一下)
4 什么是副作用,之前看别人的文章看到懵懵的,后面终于理解了,其实很简单
index.js 如下,就是导入了util.js
import './vendor/util'
vendor/util.js 如下,里面有做全局的修改或者console.log什么东西,我这里就是给全局的window加了个属性a,没有导出东西来,却使用了这个js文件,这就是副作用
// vendor/util.js
export function a() {
return 'this is function "a"';
}
export function b() {
return 'this is function "b"';
}
export function c() {
return 'this is function "c"';
}
window.a = 43
有时候我们写代码用这种写法,由于里面没有导入东西进来,webpack准确说是terser就不知道你到底要不要这个东西,万一里面有修改全局的操作你把它丢了肯定不行,如果不丢那你就要去读一遍文件才知道到底有没有副作用,官方文档说是非常耗时且因为js是动态语言所以是非常不可靠的操作,我这里仅仅是写的非常简单,工作中可能业务变得更加复杂。

Tree Shaking的基础了解完了,接下来讲下我读webpack文档的一些见解
先发2篇我读过的关于Tree Shaking较好的文章
webpack官网讲解Tree Shaking的文档:https://webpack.js.org/guides/tree-shaking/#root
你的Tree-Shaking并没什么卵用:https://segmentfault.com/a/1190000012794598
根据‘你的Tree-Shaking并没什么卵用’ 这篇文章说UglifyJS完全不能识别副作用,但是我自己做了一些测试发现,目前的webpack4.40.2是可以识别大部分副作用的。
然后讲下官网的文档,之前说了terser识别副作用特别的耗时且不准确(官方举例是react的hoc无法识别副作用),如果你能指定你的哪些文件有副作用或者所有文件都没有副作用那就皆大欢喜了,于是在package.json里出了一个属性sideEffects
接下来我做了一些测试关于sideEffects属性,注意terser的Tree Shaking只在生产环境webpack会给你调用来压缩代码,dev是不会压缩代码自然不会Tree Shaking的
第一种情况,index和util都不变,sideEffects:false,指定所有的文件都没有副作用
结果是terser完全不去管你这个文件里面写的啥,就是说你给window加个属性a没有执行
第二种情况,index和util都不变,sideEffects:["./src/vendor/util.js"],指定util是有副作用
结果terser读了util,知道了你做了什么处理,于是window加个属性a成功执行
第三种情况,index和util都不变,不加sideEffects,不告诉terser哪些有副作用,叫它自己每个引用了的文件都去看下代码
结果terser读了util,知道了你做了什么处理,于是window加个属性a成功执行
第四种情况,index变成如下代码
import { a } from './vendor/util'
结果和index使用import './vendor/util'的每种情况一样,也就是说你导入了a但是没有使用,在terser看来就是import './vendor/util'差不多
第五种情况
index变成如下代码
import { a } from './vendor/util'
console.log(a())
结果无论sideEffects怎么设置,window加个属性a都会成功
通过几次测试下来发现sideEffects属性只是针对你从文件导入了方法却没有使用(或者你压根没有导入方法)的情况生效,从这么看来sideEffects属性其实能做的优化不大,而且只是针对打包速度方面的优化(包已经打好了,访问速度跟它没有关系了),而且很坑,一个前端项目如果不只你一个人参与,你偷偷加个sideEffects属性,然后代码没压缩在dev跑的好好的,放到生产环境突然就失效了,假设人家不知道sideEffects,那抓破脑袋也不知道是咋回事(如果你就是想坑你同事,那你就可以happy了~)
深入研究webpack之Tree Shaking相关属性sideEffects用处的更多相关文章
- Webpack 4 Tree Shaking 终极优化指南
几个月前,我的任务是将我们组的 Vue.js 项目构建配置升级到 Webpack 4.我们的主要目标之一是利用 tree-shaking 的优势,即 Webpack 去掉了实际上并没有使用的代码来减少 ...
- webpack使用tree shaking的问题。及关于UglifyJs不支持ES6的解决方案。
webpack: plugins:[ new webpack.optimize.UglifyJsPlugin({ compress:{warning:true} }) ] 是的,一些dead code ...
- [Webpack 2] Tree shaking with Webpack 2
The less code you can send to the browser, the better. The concept of tree shaking basically says th ...
- Webpack 的 Tree Shaking
为什么要使用 Tree Shaking? 当从某文件模块中导出(某一个或几个变量.函数.对象等),然而这个文件模块还有许多其它(我们这次并不需要)的导出,webpack会不管三七二十一简单粗暴的将整个 ...
- webpack和tree shaking和rollup
http://blog.csdn.net/haodawang/article/details/77199980 tree shaking只对es模块生效,在打包tyscript模块是要使用tsc编译器 ...
- Webpack 4教程 - 第七部分 减少打包体积与Tree Shaking
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://wanago.io/2018/08/13/webpack-4-course-part ...
- webpack(6)-模块热替代&tree shaking
模块热替换(hot module replacement 或 HMR) 模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一.它允许在运行时 ...
- 配置Tree Shaking来减少JavaScript的打包体积
译者按: 用Tree Shaking技术来减少JavaScript的Payload大小 原文: Reduce JavaScript Payloads with Tree Shaking 译者: Fun ...
- Webpack 中的 Tree Shaking
Tree Shaking Tree shaking 用于描述移除JavaScript上下文中的未引用代码(dead-code). 为了更方便地理解tree shaking,我们可以将应用程序想象成一棵 ...
随机推荐
- 更改Nginx网站根目录以及导致的403 forbidden问题
Nginx采用默认配置,只修改了root的网站根目录位置,再访问网站的时候提示403Forbidden的错误. 仔细检查了新文件夹的权限,也对比了心就网站根目录的权限,都是一样的. 最后尝试关闭了SE ...
- c# checkedListBox设置多列横向显示 经验总结
1. 设置checkedListBox的MultiColumn 属性为true; 2. 调整checkedListBox的宽度,调整ColumnWidth的宽度
- windows安装Laravel框架经验心得(一)
作为一个程序员,要活到老学到老.虽然自己水平很菜,但是也要继续往前走,所以打算利用一些空闲时间在学习一些新知识,比如Laravel框架. 看书费劲,好不容易找到了一些关于Laravel的教学视频.不过 ...
- [noip6]模板
平衡树好题啊 现在暂时还不知道用普通线段树该咋做.... 刚刚做完 二逼平衡树,感觉自己的 \(splay\) 水平有了很大很大的长进,然鹅.... 这题又给我当头一棒.... 然后就一下午出去了但总 ...
- PGSQL基础语句汇总
一.pgsql里面的数据类型不再介绍:https://www.runoob.com/postgresql/postgresql-data-type.html 二.常用基本语句 2.1.CREATE D ...
- Python - 赋值运算符
前置知识 先了解下变量: https://www.cnblogs.com/poloyy/p/15042257.html 再了解下算术运算符: https://www.cnblogs.com/poloy ...
- Java中9种常见的CMS GC问题分析与解决
1. 写在前面 | 本文主要针对 Hotspot VM 中"CMS + ParNew"组合的一些使用场景进行总结.重点通过部分源码对根因进行分析以及对排查方法进行总结,排查过程会省 ...
- 机器学习 - k-means聚类
k-means简介 k-means是无监督学习下的一种聚类算法,简单说就是不需要数据标签,仅靠特征值就可以将数据分为指定的几类.k-means算法的核心就是通过计算每个数据点与k个质心(或重心)之间的 ...
- transform——转换
① 位移 transform:translate(x,y); 同时x轴和y轴的位移 translate(x); 在x轴上的位移 同 translateX(x) translate ...
- HCNA Routing&Switching之VLAN间路由
前文我们了解了二层交换技术vlan相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15091491.html:今天我们来聊一聊不同VLAN间通信相关话题 ...