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用处的更多相关文章

  1. Webpack 4 Tree Shaking 终极优化指南

    几个月前,我的任务是将我们组的 Vue.js 项目构建配置升级到 Webpack 4.我们的主要目标之一是利用 tree-shaking 的优势,即 Webpack 去掉了实际上并没有使用的代码来减少 ...

  2. webpack使用tree shaking的问题。及关于UglifyJs不支持ES6的解决方案。

    webpack: plugins:[ new webpack.optimize.UglifyJsPlugin({ compress:{warning:true} }) ] 是的,一些dead code ...

  3. [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 ...

  4. Webpack 的 Tree Shaking

    为什么要使用 Tree Shaking? 当从某文件模块中导出(某一个或几个变量.函数.对象等),然而这个文件模块还有许多其它(我们这次并不需要)的导出,webpack会不管三七二十一简单粗暴的将整个 ...

  5. webpack和tree shaking和rollup

    http://blog.csdn.net/haodawang/article/details/77199980 tree shaking只对es模块生效,在打包tyscript模块是要使用tsc编译器 ...

  6. Webpack 4教程 - 第七部分 减少打包体积与Tree Shaking

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://wanago.io/2018/08/13/webpack-4-course-part ...

  7. webpack(6)-模块热替代&tree shaking

    模块热替换(hot module replacement 或 HMR) 模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一.它允许在运行时 ...

  8. 配置Tree Shaking来减少JavaScript的打包体积

    译者按: 用Tree Shaking技术来减少JavaScript的Payload大小 原文: Reduce JavaScript Payloads with Tree Shaking 译者: Fun ...

  9. Webpack 中的 Tree Shaking

    Tree Shaking Tree shaking 用于描述移除JavaScript上下文中的未引用代码(dead-code). 为了更方便地理解tree shaking,我们可以将应用程序想象成一棵 ...

随机推荐

  1. 达梦数据库(DM8)大规模并行集群MPP 2节点安装部署

    达梦数据库大规模并行集群MPP 2节点安装部署   1.环境准备   os 数据库版本 ip mpp角色 centos7.x86 DM8 192.168.30.100 mpp1 centos7.x86 ...

  2. 手写一个超简单的Vue

    基本结构 这里我根据自己的理解模仿了Vue的单文件写法,通过给Vue.createApp传入参数再挂载元素来实现页面与数据的互动. 其中理解不免有错,希望大佬轻喷. 收集数据 这里将Vue.creat ...

  3. Zookeeper简介(五)

    1.定义 Zookeeper:是一个分布式的,开发源码的分布式应用程序协调服务,是hadoop的子项. 2. 特点 具有高可靠性,可扩展性,分布式,可配置的协调机制. 3. 作用 3.1 数据发布与订 ...

  4. Python - 基础数据类型 set 集合

    集合的简介 集合是一个无序.不重复的序列 它的基本用法包括成员检测和消除重复元素 集合对象也支持像 联合,交集,差集,对称差分等数学运算 集合中所有的元素放在 {} 中间,并用逗号分开 集合的栗子 这 ...

  5. 移动APP我们需要关注什么

    移动APP关注的点比web或者PC上的程序更多 1.测试用例的设计 移动互联网的快节奏,要放弃传统的测试用例编写方式,不需要写详细的测试用例,采用罗列测试点的方式如思维导图,这样既节省时间又能够直观清 ...

  6. 用QT写的简单Todo记事本-附源码(浮动窗口)

    去年边学边写了搞了很久, 已经好久没继续开发了, 先放出来供大家参考吧. 发现自己的学习能力还是不错的. 技术点: 使用QT, QML技术 代码参考: https://github.com/cnscu ...

  7. docker报错Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

    docker报错Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon run ...

  8. Android性能优化——性能优化的难题总结

    前言 现在都在谈性能优化或者在面试的时候被问到性能优化相关问题,那么我们为什么要做性能优化呢?以及性能优化的难点是什么?在整个项目周期中不同的阶段该做什么?优化效果如何长期保持?作为一名Android ...

  9. JUC学习笔记(六)

    JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html JUC学习笔记(二)https://www.cnblogs.com/lm66/p/1511 ...

  10. 全网最硬核Handler面试题深度解析

    1.简述Handler的实现原理 Android 应用是通过消息驱动运行的,在 Android 中一切皆消息,包括触摸事件,视图的绘制.显示和刷新等等都是消息.Handler 是消息机制的上层接口,平 ...