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. 图像处理算法的仿真平台之VGA时序

    一  概述 图像处理算法一般是用matla或OpenCV实现的,若是用FPGA实现,设计思路差别极大.matlab和opencv的优势:这些工具的优势在于可以方便地载入图像文件,或输出数据到图像文件, ...

  2. 高版本(8以上)tomcat不支持rest中的delete和put方式请求怎么办

    出现问题 当我们去访问delete方式和put方式: 后来才知道tomcat8以上是不支持delete方式和put方式 解决方法: 在跳转目标的jsp头文件上改为(加上了isErrorPage=&qu ...

  3. 使用宝塔配置laravel站点时,遇到open_basedir restriction in effect. 原因与解决方法

    今天一位朋友在linux服务器部署thinkphp5的时候PHP报了这个错误,如下: Warning: require(): open_basedir restriction in effect. F ...

  4. 浅析VO、DTO、DO、PO的概念、区别和用处(八)

    本篇文章主要讨论一下我们经常会用到的一些对象:VO.DTO.DO和PO. 由于不同的项目和开发人员有不同的命名习惯,这里我首先对上述的概念进行一个简单描述,名字只是个标识,我们重点关注其概念: 概念: ...

  5. Docker简易安装教程

    Docker介绍 Docker 是一种开源容器化技术,用于构建和容器化应用程序.Docker 使用客户端-服务器架构.Docker客户端与 Docker守护进程对话,后者负责构建.运行和分发 Dock ...

  6. 旧VC项目dpiAware支持

    起因 工作原因,需要维护一款VS2008 SP1开发的MFC项目, 发现WIN10高分辨率下显示模糊,不考虑升级VC版本情况下尝试解决 尝试 新版本VC中Manifest Tool>Input ...

  7. 【系统学习ES6】第一节:新的声明方式

    [系统学习ES6] 本专题旨在对ES6的常用技术点进行系统性梳理,帮助大家对其有更好的掌握.计划每周更新1-2篇,希望大家有所收获. 以前用ES5时,声明变量只能用var.ES6的出现,为我们带来了两 ...

  8. Docker未授权漏洞(2375)

    漏洞验证 直接使用浏览器访问 http://ip:2335 http://ip:2335/version http://ip:2335/info docker -H tcp://ip:2375 ver ...

  9. Genymotion模拟器安装ARM架构编译应用失败解决方案

    我们在安装一些应用到Genymotion模拟器会提示:adb: failed to install xx.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: ...

  10. 文件包含 & LFI-labs靶场

    文件包含漏洞学习 冲冲冲,好好学习 2020.1.30 认真对待自己做出的每一个决定 知识与实践 Q:什么是文件包含? A:简单一句话,为了更好地使用代码的重用性,引入了文件包含函数,可以通过文件包含 ...