webpack4.15.1 学习笔记(四) — Tree shaking
Tree shaking
本质上为了消除无用的js代码,减少加载文件体积的方式,使其整体执行时间更短。无用的代码,又有另外一种叫法:Dead Code:
- 代码不可到达,不会执行,如不可能进入的分支,return 之后的语句等
- 代码中的某个变量只有写,而没有读操作
Tree Shaking 的执行环境宿主一般是Node,而不是浏览器,且必须遵循ES6 Module规范,因为 ES6 Module 可以静态分析,可以推导出变量和导入依赖变量的引用关系。
原理
Tree-Shaking实现步骤
- 标记出模块导出值哪些没有被用过,标记功能需要配置 optimization.useExports = true 开启
- Make 阶段,收集导出变量并记录到模块依赖图ModuleGraph 变量中。
- Seal 阶段,遍历ModuleGraph 标记模块导出变量有没有被使用
- 生成产物时,若变量没有被其他模块使用时则删除对应的导出语句
- 使用Terser删除掉没有被用到的导出语句
标记效果
webpack 负责对代码进行标记,把import & export 标记为3类:
- 所有 import 标记为
/\* harmony import \*/; - 被使用过的 export 标记为
/\* harm export([type])\*/; - 未被使用过的 export 标记为
/\* unused harmony export [FuncName] \*/,其中[FuncName] 为export 的方法名称
副作用代码不可被删除
副作用是函数式编程的一个概念,是指当调用函数时,除了返回函数值之外,还会对调用函数产生附加的影响。比如console,读取和修改外部变量,导入css文件,引入Polyfill 等
会导致document.title 没有成功被设置导致出现bug。const setTitle = ()=>{
document.title = "tree shaking learn";
}
const a = setTitle(); // 虽然a变量没有被其他地方使用,但由于副作用,如果将其删除,会导致document.title 没有成功被设置导致出现bug。
如何实现 Tree shaking 的几种方法
- 执行
webpack --mode development时,打包后的代码并没有压缩且包含注释,添加--optimize-minimize命令进行压缩后。将打包后的代码压缩至一行,并删除了未引用的代码,可以把这串命令放入 package.json 的 scripts 字段中执行。 - 当没有设置 webpack mode模式时。会提示一行黄字 The 'mode' option has not been set, webpack will fallback to 'production' for this value. 因此该配置在mode=production时默认为true,也就是说webpack生产模式中,自动开启了Tree Shaking这个功能,可以直接 执行
webpack命令进行打包。 - 其实
--optimize-minimize的底层实现是一个插件UglifyJsPlugin,参考其他教程直接在webpack.config.js里配置,运行后报错,原因是在新版本的webpack中,移除了这个插件,因此该方法不可行。RemovedPluginError: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
const webpack = require('webpack');
module.exports = {
// ...
plugins:[
new webpack.optimize.UglifyJsPlugin(), // RemovedPluginError webpack.optimize.UglifyJsPlugin has been removed
],
}
- Tree Shaking并不是 webpack 的某个配置选项,而是
一组功能搭配使用后的优化效果。并且在生产模式production下自动使用。根据上述RemovedPluginError报错提示,配置optimization中的usedExports和minimize优化功能实现Tree Shaking。
module.exports = {
// ...
optimization: {
usedExports: true, // 表示在输出结果中模块只导出外部使用了的成员。
minimize: true, // 开启代码压缩优化, 删除注释、删除没有用到的代码、删除空白、替换变量名为简短的名称等,
},
};
webpack打包后,将每个模块放到一个函数中,包含成员的定义和成员的导出。
usedExports 可以标记模块导出的成员是否被外部使用,从而在打包结果中,不导出未使用的成员。标记打包后表现为:包裹模块的函数中保留定义这些成员的代码,但是移除导出它们的代码,并添加注释 /* unused harmony export */。
而函数中没有了导出它们的代码,也就表示这些成员未使用,那定义它们的代码也没有了意义,minimize就会将这些未使用的定义成员的垃圾代码一并删除。
usedExports 负责标记「枯树叶、枯树枝」
minimize 负责「摇掉」它们
总结
- Tree Shaking 用于减小文件体积
- 其工作流程是先标记,后删除
- 代码必须遵循 ES Module 规范
- 删除代码失灵很可能因出现副作用代码导致
webpack4.15.1 学习笔记(四) — Tree shaking的更多相关文章
- 官网实例详解-目录和实例简介-keras学习笔记四
官网实例详解-目录和实例简介-keras学习笔记四 2018-06-11 10:36:18 wyx100 阅读数 4193更多 分类专栏: 人工智能 python 深度学习 keras 版权声明: ...
- kvm虚拟化学习笔记(四)之kvm虚拟机日常管理与配置
KVM虚拟化学习笔记系列文章列表----------------------------------------kvm虚拟化学习笔记(一)之kvm虚拟化环境安装http://koumm.blog.51 ...
- go微服务框架kratos学习笔记四(kratos warden-quickstart warden-direct方式client调用)
目录 go微服务框架kratos学习笔记四(kratos warden-quickstart warden-direct方式client调用) warden direct demo-server gr ...
- Java IO学习笔记四:Socket基础
作者:Grey 原文地址:Java IO学习笔记四:Socket基础 准备两个Linux实例(安装好jdk1.8),我准备的两个实例的ip地址分别为: io1实例:192.168.205.138 io ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Typescript 学习笔记四:回忆ES5 中的类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- ES6学习笔记<四> default、rest、Multi-line Strings
default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...
随机推荐
- Asp-Net-Core开发笔记:使用ActionFilterAttribute实现非侵入式的参数校验
前言 在现代应用开发中,确保API的安全性和可靠性至关重要. 面向切面编程(AOP)通过将横切关注点(如验证.日志记录.异常处理)与核心业务逻辑分离,极大地提升了代码的模块化和可维护性. 在ASP.N ...
- 美团一面问我i++跟++i的区别是什么
美团一面问我i++跟++i的区别是什么 面试官:"i++跟++i的区别是什么?" 我:"i++是先使用然后再执行+1的操作,++i是先执行+1的操作然后再去使用i&quo ...
- 线程安全使用 HashMap 的四种技巧
这篇文章,我们聊聊线程安全使用 HashMap 的四种技巧. 1方法内部:每个线程使用单独的 HashMap 如下图,tomcat 接收到到请求后,依次调用控制器 Controller.服务层 Ser ...
- apisix~集成服务发现注册中心
摘要 当业务量发生变化时,需要对上游服务进行扩缩容,或者因服务器硬件故障需要更换服务器.如果网关是通过配置来维护上游服务信息,在微服务架构模式下,其带来的维护成本可想而知.再者因不能及时更新这些信息, ...
- .NET周刊【5月第3期 2024-05-19】
国内文章 WPF使用Shape实现复杂线条动画 https://www.cnblogs.com/czwy/p/18192720 文章介绍了利用WPF的Shape和动画功能,模仿CSS/SVG实现复杂的 ...
- 超详细--redis在Linux环境搭建主从复制
引言Redis是一个高性能的缓存中间件,一个Redis服务器可以支撑很多的并发请求.但是在一些超高的并发场景下,虽然Redis读写速度很快,但也会产生读写压力过大,服务器负载过高的情况.为了分担读写的 ...
- CSS——position定位属性
就像photoshop中的图层功能会把一整张图片分层一个个图层一样,网页布局中的每一个元素也可以看成是一个个类似图层的层模型.层布局模型就是把网页中的每一个元素看成是一层一层的,然后通过定位属性pos ...
- Dump Rtmp Audio Stream To AAC Formate File (从Rtmp流提取并保存AAC音频文件)
一.准备工作 参考:https://www.cnblogs.com/doudouyoutang/p/10220599.html 搭建本地rtmp服务: https://www.cnblogs.com/ ...
- 微信iOS消息拦截插件教程-手机越狱环境搭建
微信iOS消息拦截插件教程-手机越狱环境搭建 标签(空格分隔): ios越狱开发 环境 背景介绍 本教程所有内容免费 本教程来源于一次知识分享,如果有需要了解更多的 请联系QQ:480071411 i ...
- vue 的directives一个坑
大江东去,浪淘尽,千古风流人物.故垒西边,人道是,三国周郎赤壁.乱石穿空,惊涛拍岸,卷起千堆雪.江山如画,一时多少豪杰.遥想公瑾当年,小乔初嫁了,雄姿英发.羽扇纶巾,谈笑间,樯橹灰飞烟灭.故国神游,多 ...