写在前面

今天这道题目是在和小红书的一位面试官聊的时候:

我:如果要你选择一道题目来考察面试者,你最有可能选择哪一道?

面试官:那应该就是介绍一下tree shaking及其工作原理?

我:为什么?

面试官:是因为最近面了好多同学,大家都说熟悉webpack,在项目中如何去使用、如何去优化,也都或多或少会提到tree shaking,但是每当我深入去问其工作机制或者原理时,却少有人能回答上来。(小声 bb:并不是我想内卷,确实是工程师的基本素养啊,哈哈 ????)

面试官:那你来回答一下这个问题?

我:我也用过tree shaking,只是知道它的别名叫树摇,最早是由Rollup实现,是一种采用删除不需要的额外代码的方式优化代码体积的技术。但是关于它的原理,我还真的不知道,额,,,,

我们平时更多时候是停留在应用层面,这种只是能满足基础的业务诉求,对于后期的技术深挖以及个人的职业发展都是受限的。还是那句老话:知其然,更要知其所以然~

话不多说,下面我就带大家一起来深入探究这个问题。

什么是Tree shaking

Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination

这个概念,我相信大多数同学都是了解的。什么,你不懂?

不懂没关系,我可以教你啊(不过那是另外的价钱,哈哈 ????)

走远了,兄弟,让我们言归正传:tree shaking如何工作的呢?

tree shaking如何工作的呢?

虽然 tree shaking 的概念在 1990 就提出了,但直到 ES6ES6-style 模块出现后才真正被利用起来。

ES6以前,我们可以使用CommonJS引入模块:require(),这种引入是动态的,也意味着我们可以基于条件来导入需要的代码:

let dynamicModule;
// 动态导入
if (condition) {myDynamicModule = require("foo");
} else {myDynamicModule = require("bar");
}

但是CommonJS规范无法确定在实际运行前需要或者不需要某些模块,所以CommonJS不适合tree-shaking机制。在 ES6 中,引入了完全静态的导入语法:import。这也意味着下面的导入是不可行的:

// 不可行,ES6 的import是完全静态的
if (condition) {myDynamicModule = require("foo");
} else {myDynamicModule = require("bar");
}

我们只能通过导入所有的包后再进行条件获取。如下:

import foo from "foo";
import bar from "bar";if (condition) {// foo.xxxx
} else {// bar.xxx
}

ES6import语法可以完美使用tree shaking,因为可以在代码不运行的情况下就能分析出不需要的代码。

看完上面的分析,你可能还是有点懵,这里我简单做下总结:因为tree shaking只能在静态modules下工作。ECMAScript 6 模块加载是静态的,因此整个依赖树可以被静态地推导出解析语法树。所以在 ES6 中使用 tree shaking 是非常容易的。

tree shaking的原理是什么?

看完上面的分析,相信这里你可以很容易的得出题目的答案了:

  • ES6 Module引入进行静态分析,故而编译的时候正确判断到底加载了那些模块

  • 静态分析程序流,判断那些模块和变量未被使用或者引用,进而删除对应代码

common.js 和 es6 中模块引入的区别?

但到这里,本篇文章还没结束。从这道题目我们可以很容易的引申出来另外一道“明星”面试题:common.js 和 es6 中模块引入的区别?

这道题目来自冴羽大佬的阿里前端攻城狮们写了一份前端面试题答案,请查收[1]

这里就直接贴下他给出的答案了:

CommonJS 是一种模块规范,最初被应用于 Nodejs,成为 Nodejs 的模块规范。运行在浏览器端的 JavaScript 由于也缺少类似的规范,在 ES6 出来之前,前端也实现了一套相同的模块规范 (例如: AMD),用来对前端模块进行管理。自 ES6 起,引入了一套新的 ES6 Module 规范,在语言标准的层面上实现了模块功能,而且实现得相当简单,有望成为浏览器和服务器通用的模块解决方案。但目前浏览器对 ES6 Module 兼容还不太好,我们平时在 Webpack 中使用的 exportimport,会经过 Babel 转换为 CommonJS 规范。在使用上的差别主要有:

1、CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。

2、CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

3、CommonJs 是单个值导出,ES6 Module可以导出多个

4、CommonJs 是动态语法可以写在判断里,ES6 Module 静态语法只能写在顶层

5、CommonJsthis 是当前模块,ES6 Modulethisundefined

冴羽大佬的文章质量都非常高,也欢迎大家多去支持冴羽大佬,相信看完一定会对你有所收获。

总结一下

这是大厂面试问题解析的第二篇了,和之前准备写这一系列的初衷一样:我力求通过一些面试题去发掘自己未曾了解或者未曾深入了解的一个领域。

面试题更多时候是一个引子,更多是想通过面试题去思考题目背后带来的对某一模块的深入学习和探讨。

当然,每篇文章也不会只是草草给出答案,我都会尽量深入浅出的给出自己对于这道题目的理解,也会在这个基础上做一些拓展。

参考资料

[1]

阿里前端攻城狮们写了一份前端面试题答案,请查收: https://juejin.cn/post/6844904097556987917

tree shaking 及其工作原理相关推荐

  1. tree shaking的原理是什么?

    什么是tree-shaking 别名叫摇晃树,最早是由Rollup实现,是一种采用删除不需要的额外代码的方式优化代码体积的技术 tree-shaking会在打包过程中 静态分析 模块之间的导入导出,确 ...

  2. Webpack 实现 Tree shaking 的前世今生

    作者 | 左琳       责编 | 欧阳姝黎 前言 如果看过 rollup 系列的这篇文章 - 无用代码去哪了?项目减重之 rollup 的 Tree-shaking,那你一定对 tree-shak ...

  3. webpack 打包(plugin、loader 工作原理)

    模块化工具 由来 ES Modules 存在环境兼容问题 模块文件过多,网络请求频繁 所有的前端资源都需要模块化 概要 Webpack 作为 模块打包器(Module bundler),可以把零散的文 ...

  4. 无用代码去哪了?项目减重之 rollup 的 Tree shaking

    左琳,微医前端技术部前端开发工程师.身处互联网浪潮之中,热爱生活与技术. Tip:本文所用 rollup 打包工具版本为 rollup v2.47.0. 从 Webpack2.x 通过插件逐步实现 t ...

  5. javascript原理_JavaScript程序包管理器工作原理简介

    javascript原理 by Shubheksha 通过Shubheksha JavaScript程序包管理器工作原理简介 (An introduction to how JavaScript pa ...

  6. Struts2的工作原理

    Struts2是在Struts1的基础上发展而来的,Struts是WebWork和Struts1的集合,采用的正是WebWork的核心,更多的是WebWork. 下载的Struts2源代码文件 主要的 ...

  7. 数据库索引的工作原理及其种类

    数据库索引的工作原理及其种类 数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询.更新数据库表中数据.索引的实现通常使用B树及其变种B+树. 在数据之外,数据库系统还维护着满足特定查找算 ...

  8. 图解 Git 工作原理

    来源:深度学习爱好者本文约2600字,建议阅读5分钟本文图解Git中的最常用命令.如果你稍微理解Git的工作原理,这篇文章能够让你理解的更透彻. 基本用法 上面的四条命令在工作目录.暂存目录(也叫做索 ...

  9. 人类将可能操控AI?神经网络语言处理工作原理被破解

    近期,来自麻省理工学院计算机科学人工智能实验室(CSAIL)和卡塔尔计算研究所的研究人员已经通过新的解释技术,来分析神经网络做机器翻译和语音识别的训练过程. 神经网络通过分析大量的训练数据来学习并执行 ...

最新文章

  1. 安卓使用ImageView显示OpenCV-Mat
  2. Java中对象和引用的理解
  3. Netty 的基本简单实例【服务端-客户端通信】
  4. 分布式搜索elasticsearch 索引文档的增删改查 入门
  5. 通俗易懂!视觉slam第八部分——李群,李代数
  6. 腾讯云加码 IDaaS,加速 SaaS 时代进程
  7. C++11 static_assert(转载)
  8. SPI 机制-插件化扩展功能
  9. Spring AOP原理分析(四)--AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation源码解析
  10. 计算机上安装的游戏怎么删除,win7自带游戏安装包太占内存怎么删除?
  11. dnf服务器字体文件,DNF普通伤害字体怎么改为超时空漩涡字体_字体制作方法分享_3DM网游...
  12. Excel VBA小游戏,上班摸鱼必备
  13. 用Hight-Speed Charting绘制时间电压动态曲线
  14. pip3.7.5安装环境依赖onnxruntime、onnx、numpy、skl2onnx
  15. 有关MAC、PHY和MII
  16. 2023年全国最新二级建造师精选真题及答案15
  17. mysql 页分裂_InnoDB中的页合并与分裂
  18. redis哨兵模式出现connected_slaves:0解决办法
  19. IT开发部门怎样利用RPA机器人解放人力
  20. 二级页面全屏html,还是二级网页不能全屏怎么办? 爱问知识人

热门文章

  1. Nginx服务器常用的几个操作命令
  2. 到底什么是文件描述符???
  3. mapgis10-10.25
  4. Python---turtle模块---美国国旗的绘画
  5. Homebrew安装以及解决遇到的问题mac小白教程
  6. 汉字拼音带声调和发音mp3文件(C#源程序)
  7. linux EHCI DRIVER之中断处理函数ehci_irq()分析(二)
  8. 区块链技术用解决拜占庭将军问题_什么是拜占庭将军问题
  9. 恨铁不成钢 苹果Siri为何敌不过其它智能助理?
  10. 一个6年普通码农的普通经历