「前端每日一问(54)」什么是Tree-Shaking?Vue3 是如何支持 Tree-Shaking 的?

668 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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 是如何工作的。

文件目录结构如下:

image.png

// 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 模板在线编译展示,链接

image.png

模板为空,引入 null。

image.png

如果加了一个 div,就会引入一些新的东西,比如 openBlockcreateElementBlock,真的使用到了,这些东西才会被打包进去。

如果再加一些东西,比如 keep-alive、transition,就再引入他们对应的模块。

image.png

很显然,Vue3 把各个模块进行了拆分,如果不引入某个模块,就不会被打包进最终构建资源里。

另外,Vue3 为了更好地配合 tree-shaking,还在源码中使用了大量的注释代码 /*#__PURE__*/

image.png

Vue 是用 rollup 打包的,这个注释代码的作用就是告诉 rollup,注释代码后面定义的这些函数没有副作用,可以放心地 Tree-Shaking,一旦没有用到它,就不打包进最终的构建文件里。

解释一下,这里的副作用是指函数里的逻辑可能影响别的模块,rollup 有时不好判断一个函数是否有副作用,需要开发者用这个注释代码声明一下。

其实源码的注释里也有解释,如下图:

image.png

结尾

本文参考:Vue.js设计与实现

阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~

如果我的文章对你有帮助,你的👍就是对我的最大支持^_^

你也可以关注《前端每日一问》这个专栏,防止失联哦~

我是阿林,输出洞见技术,再会!

上一篇:

「前端每日一问(53)」如何实现字符串的 padStart 函数

下一篇:

「前端每日一问(55)」检查字符串是否是有效的括号