你忽略的tree shaking

96 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

前言

大家好,我是小阵 🔥,一路奔波不停的码字业务员
如果喜欢我的文章,可以关注 ➕ 点赞,与我一同成长吧~😋
加我微信:zzz886885,邀你进群,一起学习交流,摸鱼学习两不误🌟

开开心心学技术大法~~

开心

来了来了,他真的来了~

正文

问题起始

之前我以为是tree shaking会忽略整个引入但未使用的文件,后来发现好像不太对

比如:

// testTreeShaking.js
console.log('我是treeShaking',);
​

在入口文件

// index.js
import './testTreeShaking'

我以为打包之后会完全将testTreeShaking.js文件给忽略

最终却是发现,console.log('我是treeShaking')依然会被打包到bundle中。

详细情况

后续经过验证发现,原来tree shaking针对的是引入但未使用的module

这个module并不是只每一个文件module,而是文件module中暴露的子module。

看上去好像有点绕

举个例子就清楚了:

修改testTreeShaking.js

// testTreeShaking.js
console.log('我是treeShaking',);
​
const add = function () {
  console.log('我是add')
}
const squ = () => {
  console.log('我是squ')
}
export {
  add,
  squ
}

情况一

入口文件中

// index.js
import './testTreeShaking'

testTreeShaking.js中暴露出来的addsqu都不会被打包,但是console.log('我是treeShaking')这个内容会被打包

情景二

入口文件中

// index.js
import { add } from './testTreeShaking'

testTreeShaking.js中暴露出来的addsqu依然不会被打包,但是console.log('我是treeShaking')这个内容会被打包。

因为虽然add被引入了,但是未被使用

情景三

入口文件中

// index.js
import { add } from './testTreeShaking'
console.log('add',add)

testTreeShaking.js中暴露出来的add会被打包,squ不会被打包,console.log('我是treeShaking')`这个内容会依然被打包。

因为虽然add被引入了,也被使用了,而squ不管是否引用,参照情景一情景二来分析,都是不会被打包的

上面可以看到console.log('我是treeShaking')永远会被打包,那假设定义一个未被使用的function或变量,他们会被忽略吗

情景四

修改testTreeShaking.js为:

// testTreeShaking.js
console.log('我是treeShaking',);
const v = '我是变量v'
function other(){
  console.log('我是other')
}
const add = function () {
  console.log('我是add')
}
const squ = () => {
  console.log('我是squ')
}
export {
  add,
  squ
}

入口文件为

// index.js
import './testTreeShaking'

发现不仅function other和变量v没有被打包,连console.log('我是treeShaking')也没有被打包

忽略引入但未使用文件

如果想要将整个文件都忽略也可以使用webpack4推出的sideEffects,可以选在在package.json文件中或者在webpack.config.js文件中手动配置optimization.sideEffectsRule.sideEffects

package.json中

// ...
"sideEffects": [
  "**/*.css",
  "**/*.scss",
  "./esnext/index.js",
  "./esnext/configure.js"
],
// ...

可以为boolean或数组

  • true时跟[]相当

  • false表示关闭sideEffects,关闭之后tree shaking将不再针对整体文件做取舍

  • []内部表示拥有副作用的,也就是项目中会起到作用的代码,这些代码会被打包,以外的其他引入但未使用的文件都会被忽略

补充

开启tree shaking需要

  • 使用 ES2015 模块语法(即 importexport)。

  • 确保没有编译器将您的 ES2015 模块语法转换为 CommonJS 的(顺带一提,这是现在常用的 @babel/preset-env 的默认行为,详细信息请参阅文档)。

  • 【可选】在项目的 package.json 文件中,添加 "sideEffects" 属性。

  • 使用 mode"production" 的配置项以启用更多优化项,包括压缩代码与 tree shaking。

结语

如果文章真的有帮到你,希望可以多多点赞、收藏、关注支持一波呀!!小阵会很开心哒~

文章如有错误或不严谨之处,还望指出,感谢感谢!!!

加油!

往期好文推荐「我不推荐下,大家可能就错过了史上最牛逼vscode插件集合啦!!!(嘎嘎~)😄」