删除项目中无用代码的两种方式(实用)

17,902 阅读4分钟

帮帝王蟹 review 代码,发现了他要重构的项目中,存在很多无用的 console.log(xxx) 的代码。

帝王蟹准备全局搜索 console.log ,然后挨个删除,但是代码中实在是太多了。

如果挨个去删,这种感觉就好像:遇见喜欢的人跟好朋友手牵手,心里明明想xx,却迟迟不敢动手。。。

所以,现在思路就是,拿到代码中所有的 console.log(xxx),并对其进行删除,提供两种方案:

方案一

webpack 的 loader 本质上其实就是一个函数,我们可以在这个函数内部,根据正则匹配出我们想删除的字符串,对其进行替换。

自定义 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')]
 },

使用前后源代码打包对比:

const name = '爱情'
console.log(name)

使用前(正常打包)

使用后(去除了 console.log)

这种方式虽简单,但对于一些类似简单的需求(匹配、删除、替换等),足矣。

就好像爱情,不需要复杂的海誓山盟,只需要简单的你在我身旁。

方案二

不熟悉 babel 的小伙伴可以留言,后面出一篇,其实就是编译原理的一些内容。

比如 webpack 打包原理的几个核心步骤就是利用了 babel (简单提一嘴,不展开说打包原理,后续单独写一篇)

  • 获取主入口内容
  • 分析主入口模块(@babel/parser包、转AST)
  • 对模块内容进行处理 (@babel/traverse包、遍历AST收集依赖)
  • 递归所有模块
  • 生成最终代码

回到正题,我们可以自定义 babel plugin,删除无用代码。

通过 babel 拿到源代码 parsing 之后的 AST,然后匹配出我们的目标节点,对目标节点进行转换、删除等操作,生成新的 AST(去除 console.los(xxx) 之后的 AST)。

先通过 https://astexplorer.net/ 在线转换网站,看一下我们想删除的 AST 节点:

通过上图,需求已经很明朗了。

自定义 plugins/ignore-console-log-plugin.js 结合着图看一下,代码就很清晰了,如下:

// babel 版的工具库,提供了很多 AST 的 Node 节点相关的工具函数
const types = require("@babel/types")

// 规则
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
      // 规则命中
      if (map.get(objectName) === propertyName) {
       // 移除
       path.remove()
      }
     }
    }
   },
  },
 }
}

使用姿势 (webpack 项目中),在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/'
}

使用前后源代码打包对比:

const name = '想太多'
console.log(name)

使用前(正常打包)

使用后(去除了 console.log)

小结

解决问题的方式有很多种,选择最合适的最舒服。