一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情。
本题难度:⭐ ⭐
本题类型:构建工具
问:什么是 Tree-Shaking?
答:
Tree-Shaking 因 rollup.js 而普及,简单来说,Tree-Shaking 是指擦除那些不会执行的代码,webpack 也支持 Tree-Shaking。
我们知道,只要是被写进项目的代码,都会经过 http 请求返回到浏览器端,如果一些被引入项目的代码都不会被执行,那么这些代码就白白占用了项目的打包体积,打包体积大,http 请求的速度也会减慢,页面的性能也会受到影响。
Tree-Shaking 就可以把项目中没有使用的代码(dead code)擦除掉,举个例子,Vue 内部内置了很多组件,例如 <Transition>,如果我们的项目中根本就没有用到该组件,就会被 Tree-Shaking 自动忽略掉,它的代码不会被打包到项目最终的构建资源中。
想要实现 Tree-Shaking,必须满足一个条件,即模块必须是 ESM(ES Module),因为 Tree-Shaking 依赖 ESM 的静态结构。
下面我们就使用 webpack 来感受一下 Tree-Shaking 是如何工作的。
文件目录结构如下:
// a.js
export function foo (obj) {
obj && obj.foo
}
export function bar (obj) {
obj && obj.bar
}
// index.js
import { foo } from './a'
foo()
a.js 文件里有两个函数 foo 和 bar,在 index.js 里只引入 foo 函数。
运行命令 npx webpack 打包,生成的文件为 dist/main.js,代码如下:
// dist/main.js
(()=>{"use strict";console.log("foo")})();
可以发现,只打包了 foo 函数的内容,没有引用的 bar 函数不会被打包进去,因为 Tree-Shaking 起了作用。
问:Vue3 是如何支持 Tree-Shaking 的?
尤雨溪是这么回答的:
下面的截图是 vue3 模板在线编译展示,链接
模板为空,引入 null。
如果加了一个 div,就会引入一些新的东西,比如 openBlock、createElementBlock,真的使用到了,这些东西才会被打包进去。
如果再加一些东西,比如 keep-alive、transition,就再引入他们对应的模块。
很显然,Vue3 把各个模块进行了拆分,如果不引入某个模块,就不会被打包进最终构建资源里。
另外,Vue3 为了更好地配合 tree-shaking,还在源码中使用了大量的注释代码 /*#__PURE__*/。
Vue 是用 rollup 打包的,这个注释代码的作用就是告诉 rollup,注释代码后面定义的这些函数没有副作用,可以放心地 Tree-Shaking,一旦没有用到它,就不打包进最终的构建文件里。
解释一下,这里的副作用是指函数里的逻辑可能影响别的模块,rollup 有时不好判断一个函数是否有副作用,需要开发者用这个注释代码声明一下。
其实源码的注释里也有解释,如下图:
结尾
本文参考:Vue.js设计与实现
阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~
如果我的文章对你有帮助,你的👍就是对我的最大支持^_^
你也可以关注《前端每日一问》这个专栏,防止失联哦~
我是阿林,输出洞见技术,再会!
上一篇:
「前端每日一问(53)」如何实现字符串的 padStart 函数
下一篇: