手写清除console的loader
前言
作为一个前端,对于console.log的调试可谓是相当熟悉,话不多说就是好用!帮助我们解决了很多bug^_^
但是!有因必有果(虽然不知道为什么说这句但是很顺口),如果把console发到生产环境也是很头疼的,尤其是如果打印的信息很私密的话,可能要凉凉TT
删除console方式介绍
对于在生产环境必须要清除的console语句,如果手动一个个删除,听上去就很辛苦,因此这篇文章本着看到了就要学,学到了就要用的精神我打算介绍一下手写loader的方式清除代码中的console语句,在此之前也介绍一下其他可以清除console语句的方式吧哈哈
1. 方式一:暴力清除
通过编辑器查找所有console,或者eslint编译时的报错提示定位语句,然后清除,就是有点费手,不够优雅
因此下面需要介绍几种优雅的清除方式
2. 方式二 :uglifyjs-webpack-plugin
该插件可用于压缩我们的js代码,同时可以通过配置去掉console语句,安装后配置在webpack的optimization下,即可使用,需要注意的是:此配置只在production环境下生效
安装
npm i uglifyjs-webpack-plugin
其中drop_console和pure_funcs的区别是:
drop_console的配置值为boolean,也就是说如果为true,那么代码中所有带console前缀的调试方式都会被清除,包括console.log,console.warn等
pure_funcs的配置值是一个数组,也就是可以配置清除那些带console前缀的语句,截图中配的是
['console.log']
,因此生产环境上只会清除console.log,如果代码中包含其他带console的前缀,如console.warn则保留
但是需要注意的是,该方法只对ES5语法有效,如果你的代码中涉及ES6就会报错
3. 方式三:terser-webpack-plugin
webpack v5 开箱即带有最新版本的
terser-webpack-plugin
。如果你使用的是 webpack v5 或更高版本,同时希望自定义配置,那么仍需要安装terser-webpack-plugin
。如果使用 webpack v4,则必须安装terser-webpack-plugin
v4 的版本。
安装
npm i terser-webpack-plugin@4
terser-webpack-plugin对于清楚console的配置可谓是跟uglifyjs-webpack-plugin一点没差,但是他们最大的差别就是TerserWebpackPlugin支持ES6的语法
4. 方式四:手写loader删除console
终于进入了主题了,朋友们
什么是loader
众所周知,webpack只能理解js,json等文件,那么除了js,json之外的文件就需要通过loader去顺利加载,因此loader在其中担任的就是翻译工作。loader可以看作一个node模块,实际上就是一个函数,但他不能是一个箭头函数,因为它需要继承webpack的this,可以在loader中使用webpack的方法。
单一原则,一个loader只做一件事
调用方式,loader是从右向左调用,遵循链式调用
统一原则,输入输出都是字符串或者二进制数据
根据第三点,下面的代码就会报错,因为输出的是数字而不是字符串或二进制数据
module.exports = function(source) {
return 111
}
新建清除console语句的loader
首先新建一个dropConsole.js文件
// source:表示当前要处理的内容
const reg = /(console.log\()(.*)(\))/g;
module.exports = function(source) {
// 通过正则表达式将当前处理内容中的console替换为空字符串
source = source.replace(reg, "")
// 再把处理好的内容return出去,坚守输入输出都是字符串的原则,并可达到链式调用的目的供下一个loader处理
return source
}
在webpack的配置文件中引入
module: {
rules:[
{
test: /\.js/,
use: [
{
loader: path.resolve(__dirname, "./dropConsole.js"),
options: {
name: "前端"
}
}
]
},
{
]
}
在webpack的配置中,loader的导入需要绝对路径,否则导入失效,如果想要像第三方loader一样引入,就需要配置resolveLoader 中的modules属性,告诉webpack,当node_modules中找不到时,去别的目录下找
module: {
rules:[
{
test: /\.js/,
use: [
{
loader: 'dropConsole',
options: {
name: "前端"
}
}
]
},
{
]
}
resolveLoader:{
modules:["./node_modules","./build"] //此时我的loader写在build目录下
},
正常运行后,调试台将不会打印console信息
最后介绍几种在loader中常用的webpack api
this.query:返回webpack的参数即options的对象
this.callback:同步模式,可以把自定义处理好的数据传递给webpack
const reg = /(console.log\()(.*)(\))/g;
module.exports = function(source) {
source = source.replace(reg, "");
this.callback(null,source);
// return的作用是让webpack知道loader返回的结果应该在this.callback当中,而不是return中
return
}
this.async():异步模式,可以大致的认为是this.callback的异步版本,因为最终返回的也是this.callback
const path = require('path')
const util = require('util')
const babel = require('@babel/core')
const transform = util.promisify(babel.transform)
module.exports = function(source,map,meta) {
var callback = this.async();
transform(source).then(({code,map})=> {
callback(null, code,map)
}).catch(err=> {
callback(err)
})
};
最后的最后,webpack博大精深,值得我们好好学习,深入研究!
作者:我也想一夜暴富
来源:https://juejin.cn/post/7038413043084034062