webpack之babel-loader使Tree-shaking失效

前言

由于早期webpack发展非常快,变化也比较多,所以当我们去找资料时,我们得到的结果并不一定适用于我们当前使用的版本,对于Tree-shaking也是如此。 很多资料都表示,如果我们使用了babel-loader,就会导致Tree-shaking失效。

一、babel-loader导致Tree-shaking失效的原因

Tree-shaking实现的前提是必须要使用ES Modules去组织我们的代码,也就是说由webpack打包的代码必须使用ESM。
webpack在打包所有模块之前,先是将模块根据配置交给不同的loader去处理,最后再将所有loader处理过后的结果打包到一起。
为了转换代码中的ECMAScript新特性,很多时候我们都会选择babel-loader去处理我们的js文件。而在babel转换我们的代码时,就有可能处理掉我们代码中的ES Modules把它们转换成CommonJS,这取决于我们有没有使用转换ESM的插件。
我们所使用的preset-env插件集合,它里面就有这么一个插件,所以当preset-env这个插件集合开始工作的时候,我们代码中ESM的部分就应该会被转换成CommonJS的方式,webpack打包时拿到的代码就是以CommonJS组织的代码,所以Tree-shaking就不能生效。

二、配置babel-loader后尝试打包

// webpack.config.js
module.exports = {
    mode:"none",
    entry:"./src/main.js",
    output:{
        filename:"bundle.js"
    },
    module:{
        rules:[
            {
                test:/\.js$/,
                use:[
                    {
                        loader:"babel-loader",
                        options:{
                            presets:['@babel/preset-env']
                        }
                    }
                ]
            }
        ]
    },
    // optimization是用来集中配置一些webpack优化功能的
    optimization:{
        usedExports:true, // 表示输出结果中只导出那些在外部使用了的成员
    }
}

执行打包

在这里插入图片描述
我们发现usedExports功能正常执行了,也就是说如果我们开启minimize压缩代码的话,这些未引用代码依然会被移除,Tree-shaking并没有失效。
这是因为在最新版本的babel-loader中,已经自动帮我们关闭了ESM转换的插件。
在这里插入图片描述
我们可以在babel-loader/lib/injectCaller.js中看到当前是支持ESM的。
在这里插入图片描述
而在preset-env中根据injectCaller.js中的标识禁用了ESM的转换。

所以最后webpack最终打包时得到的还是ESM组织的代码,Tree-shaking也就可以正常工作了。

如果不确定ESM转换是否被禁用,我们还可以手动禁用,确保webpack最终打包的是ESM的代码。

presets:[ 
	// 注意,这里的结构,还是一个数组
	// 如果想要转CommonJS,可以设置成modules: "commonjs"
    ['@babel/preset-env', { modules: false }]
]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值