刪除項(xiàng)目中無用代碼的兩種方案(實(shí)用)
幫帝王蟹(封面男主) review 代碼,發(fā)現(xiàn)了他要重構(gòu)的項(xiàng)目中,存在很多無用的 console.log(xxx) 的代碼。
帝王蟹準(zhǔn)備全局搜索 console.log ,然后挨個(gè)刪除,但是代碼中實(shí)在是太多了。
如果挨個(gè)去刪,這種感覺就好像:遇見喜歡的人跟好朋友手牽手,心里明明想xx,卻遲遲不敢動(dòng)手。。。

所以,現(xiàn)在思路就是,拿到代碼中所有的 console.log(xxx),并對(duì)其進(jìn)行刪除,提供兩種方案:
方案一
webpack 的 loader 本質(zhì)上其實(shí)就是一個(gè)函數(shù),我們可以在這個(gè)函數(shù)內(nèi)部,根據(jù)正則匹配出我們想刪除的字符串,對(duì)其進(jìn)行替換。
自定義 loaders/ignore-console-log-loader.js 代碼很簡單,如下:
const?reg?=?/(console.log\()(.*)(\))/g
module.exports?=?function?(sourceCode)?{
?return?sourceCode.replace(reg,?'')
}
使用姿勢,在webpack.config.js 配置文件中添加一下自定義的 loader :
module:?{
??rules:?[
???{
????test:?/\.js$/,
????loader:?['ignore-console-log-loader'],
???},
??]
?},
?resolveLoader:?{
??//?指定自定義?loader?的位置目錄
??modules:?['node_modules',?path.resolve(__dirname,?'loaders')]
?},
使用前后源代碼打包對(duì)比:
const?name?=?'愛情'
console.log(name)
使用前(正常打包)

使用后(去除了 console.log)

這種方式雖簡單,但對(duì)于一些類似簡單的需求(匹配、刪除、替換等),足矣。
就好像愛情,不需要復(fù)雜的海誓山盟,只需要簡單的你在我身旁。
方案二
★不熟悉 babel 的小伙伴可以留言,后面出一篇,其實(shí)就是編譯原理的一些內(nèi)容。
”
比如 webpack 打包原理的幾個(gè)核心步驟就是利用了 babel (簡單提一嘴,不展開說打包原理,后續(xù)單獨(dú)寫一篇)
獲取主入口內(nèi)容 分析主入口模塊(@babel/parser包、轉(zhuǎn)AST) 對(duì)模塊內(nèi)容進(jìn)行處理 (@babel/traverse包、遍歷AST收集依賴) 遞歸所有模塊 生成最終代碼
回到正題,我們可以自定義 babel plugin,刪除無用代碼。
通過 babel 拿到源代碼 parsing 之后的 AST,然后匹配出我們的目標(biāo)節(jié)點(diǎn),對(duì)目標(biāo)節(jié)點(diǎn)進(jìn)行轉(zhuǎn)換、刪除等操作,生成新的 AST(去除 console.los(xxx) 之后的 AST)。
先通過 https://astexplorer.net/ 在線轉(zhuǎn)換網(wǎng)站,看一下我們想刪除的 AST 節(jié)點(diǎn):

通過上圖,需求已經(jīng)很明朗了。
自定義 plugins/ignore-console-log-plugin.js 結(jié)合上圖看一下,代碼就很清晰了,如下:
//?babel?版的工具庫,提供了很多?AST?的?Node?節(jié)點(diǎn)相關(guān)的工具函數(shù)
const?types?=?require("@babel/types")
//?規(guī)則
const?map?=?new?Map()
map.set('console',?'log')
//?...
module.exports?=?function?declare()?{
?return?{
??name:?"ignore-console-log",
??visitor:?{
???ExpressionStatement(path)?{
????const?expression?=?path.node.expression
????if?(types.isCallExpression(expression))?{
?????const?callee?=?expression.callee
?????if?(types.isMemberExpression(callee))?{
??????//?獲取到?console
??????const?objectName?=?callee.object.name
??????//?獲取到?log
??????const?propertyName?=?callee.property.name
??????//?規(guī)則命中
??????if?(map.get(objectName)?===?propertyName)?{
???????//?移除
???????path.remove()
??????}
?????}
????}
???},
??},
?}
}
使用姿勢 (webpack 項(xiàng)目中),在webpack.config.js 配置文件中添加一下自定義的 plugin :
{
??test:?/\.js$/,
??use:?{
???loader:?'babel-loader',
???options:?{
????"presets":?['@babel/preset-env'],
????"plugins":?['./plugins/ignore-console-log-plugin.js']
???}
??},
??exclude:?'/node_modules/'
}
使用前后源代碼打包對(duì)比:
const?name?=?'想太多'
console.log(name)
使用前(正常打包)

使用后(去除了 console.log)

重慶擺龍門陣,俗稱嘮嗑
★本文源碼已收錄https://github.com/ponkans,歡迎 Star,持續(xù)接水??
”
解決問題的方式有很多種,選擇最合適的最舒服。
就好像感情,再多的花里胡哨,也抵不過我們不合適幾個(gè)字。
我是接水怪,一個(gè)沒什么感情的程序猿。

