写在后面
明天这道题目是在和小红书的一位面试官聊的时候:
我:如果要你抉择一道题目来考查面试者,你最有可能抉择哪一道?
面试官:那应该就是介绍一下 tree shaking
及其工作原理?
我:为什么?
面试官:是因为最近面了好多同学,大家都说相熟webpack
,在我的项目中如何去应用、如何去优化,也都或多或少会提到tree shaking
,然而每当我深刻去问其工作机制或者原理时,却少有人能答复上来。(小声 bb:并不是我想内卷,的确是工程师的根本素养啊,哈哈 ????)
面试官:那你来答复一下这个问题?
我:我也用过 tree shaking
,只是晓得它的别名叫 树摇
,最早是由Rollup
实现,是一种采纳 删除不须要的额定代码的形式优化代码体积
的技术。然而对于它的原理,我还真的不晓得,额,,,,
咱们平时更多时候是停留在利用层面,这种只是能满足根底的业务诉求,对于前期的技术深挖以及集体的职业倒退都是受限的。还是那句老话:知其然,更要知其所以然~
话不多说,上面我就带大家一起来深刻探索这个问题。
什么是Tree shaking
Tree shaking
是一种通过革除多余代码形式来优化我的项目打包体积的技术,专业术语叫Dead code elimination
这个概念,我置信大多数同学都是理解的。什么,你不懂?
不懂没关系,我能够教你啊(不过那是另外的价格,哈哈 ????)
走远了,兄弟,让咱们言归正传:tree shaking
如何工作的呢?
tree shaking
如何工作的呢?
尽管 tree shaking
的概念在 1990 就提出了,但直到 ES6
的 ES6-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}
ES6
的 import
语法能够完满应用tree shaking
,因为能够在代码不运行的状况下就能剖析出不须要的代码。
看完下面的剖析,你可能还是有点懵,这里我简略做下总结:因为 tree shaking
只能在动态 modules
下工作。ECMAScript 6
模块加载是动态的, 因而整个依赖树能够被动态地推导出解析语法树。所以在 ES6
中应用 tree shaking
是非常容易的。
tree shaking
的原理是什么?
看完下面的剖析,置信这里你能够很容易的得出题目的答案了:
ES6 Module
引入进行动态剖析,故而编译的时候正确判断到底加载了那些模块- 动态分析程序流,判断那些模块和变量未被应用或者援用,进而删除对应代码
common.js 和 es6 中模块引入的区别?
但到这里,本篇文章还没完结。从这道题目咱们能够很容易的引申进去另外一道“明星”面试题:common.js 和 es6 中模块引入的区别?
这道题目来自 冴羽
大佬的阿里前端攻城狮们写了一份前端面试题答案,请查收
这里就间接贴下他给出的答案了:
CommonJS
是一种模块标准,最后被利用于 Nodejs
,成为 Nodejs
的模块标准。运行在浏览器端的 JavaScript
因为也短少相似的标准,在 ES6
进去之前,前端也实现了一套雷同的模块标准 (例如: AMD
),用来对前端模块进行治理。自 ES6
起,引入了一套新的 ES6 Module
标准,在语言规范的层面上实现了模块性能,而且实现得相当简略,无望成为浏览器和服务器通用的模块解决方案。但目前浏览器对 ES6 Module
兼容还不太好,咱们平时在 Webpack
中应用的 export
和 import
,会通过 Babel
转换为 CommonJS
标准。在应用上的差异次要有:
1、CommonJS
模块输入的是一个值的拷贝,ES6
模块输入的是值的援用。
2、CommonJS
模块是运行时加载,ES6
模块是编译时输入接口。
3、CommonJs
是单个值导出,ES6 Module
能够导出多个
4、CommonJs
是动静语法能够写在判断里,ES6 Module
动态语法只能写在顶层
5、CommonJs
的 this
是以后模块,ES6 Module
的 this
是 undefined
冴羽
大佬的文章品质都十分高,也欢送大家多去反对 冴羽
大佬,置信看完肯定会对你有所播种。
总结一下
这是 大厂面试问题解析
的第二篇了,和之前筹备写这一系列的初衷一样:我力求通过一些面试题去挖掘本人未曾理解或者未曾深刻理解的一个畛域。
面试题更多时候是一个引子,更多是想通过面试题去思考题目背地带来的对某一模块的深刻学习和探讨。
当然,每篇文章也不会只是草草给出答案,我都会尽量深入浅出的给出本人对于这道题目的了解,也会在这个根底上做一些拓展。