携手创作,共同成长!这是我参与「掘金日新计划 · 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中暴露出来的add和squ都不会被打包,但是console.log('我是treeShaking')这个内容会被打包
情景二
入口文件中
// index.js
import { add } from './testTreeShaking'
testTreeShaking.js中暴露出来的add和squ依然不会被打包,但是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.sideEffects和Rule.sideEffects
package.json中
// ...
"sideEffects": [
"**/*.css",
"**/*.scss",
"./esnext/index.js",
"./esnext/configure.js"
],
// ...
可以为boolean或数组
-
true时跟[]相当 -
false表示关闭sideEffects,关闭之后tree shaking将不再针对整体文件做取舍 -
[]内部表示拥有副作用的,也就是项目中会起到作用的代码,这些代码会被打包,以外的其他引入但未使用的文件都会被忽略- 具体匹配规则可以参考glob-to-regexp
补充
开启tree shaking需要
-
使用 ES2015 模块语法(即
import和export)。 -
确保没有编译器将您的 ES2015 模块语法转换为 CommonJS 的(顺带一提,这是现在常用的 @babel/preset-env 的默认行为,详细信息请参阅文档)。
-
【可选】在项目的
package.json文件中,添加"sideEffects"属性。 -
使用
mode为"production"的配置项以启用更多优化项,包括压缩代码与 tree shaking。- 因为
"production"时默认开启 ModuleConcatenationPlugin,所以tree shaking才会生效,也可以通过在"development"中手动开启 ModuleConcatenationPlugin
- 因为
结语
如果文章真的有帮到你,希望可以多多点赞、收藏、关注支持一波呀!!小阵会很开心哒~
文章如有错误或不严谨之处,还望指出,感谢感谢!!!
往期好文推荐「我不推荐下,大家可能就错过了史上最牛逼vscode插件集合啦!!!(嘎嘎嘎~)😄」