webpack:自定义loader删除项目中的console

发布时间 2023-04-25 09:07:19作者: spongeCoder

简介

本文章主要是用于将react代码中杂乱的console在发布到生产环境的时候进行清理;

需要准备的依赖

1、@babel/parser:将源代码解析成AST

2、@babel/traverse:循环遍历AST节点

3、@babel/generator:将ast转换成js代码

4、@babel/types:操作ast的方法集合

思路

实现的主要思路是在打包的时候使用 '@babel/parser' 将js、jsx、ts、tsx 转成 AST(抽象语法树),然后使用'@babel/traverse'遍历AST节点将对应的方法使用xxxx判断节点将对应的console.log或者 warn等方法删除掉 ,最后s使用'@babel/generator'将操作后的AST在转回 代码;

实现

1、webpack配置

options为传入自定义loader 的配置,removes为需要删除的console的方法 默认为log

{
          test: /\.(js|mjs|jsx|ts|tsx)$/,
          exclude: /node_modules/,
          use: [
            {
              loader: path.resolve(__dirname, './removeConsole.js'),
              options: {
                removes: ['log', 'warn']
              }
            }
          ],
        }

2、自定义loader实现

const parser = require('@babel/parser') //将源代码解析成AST
const traverse = require('@babel/traverse').default; //循环遍历AST节点
const generator = require('@babel/generator').default; //将ast转换成js代码
const t = require('@babel/types'); //操作ast的方法集合

module.exports = async function (source) {

    const { removes = ['log'] } = this.getOptions()

    let ast = parser.parse(source, {
        // parse in strict mode and allow module declarations
        sourceType: "module",
        plugins: [
            // enable jsx and flow syntax
            "jsx",
            "flow",
        ],
    })

    traverse(ast, { //循环
        enter(path) {
            if (
                t.isMemberExpression(path.node.callee)
                && t.isIdentifier(path.node.callee.object, { name: 'console' })
            ) {
                for (let i = 0; i < removes.length; i++) {
                    let name = removes[i]
                    if (t.isIdentifier(path.node.callee.property, { name: name })) {
                        path.remove()
                        break
                    }
                }
            }
        }
    })

    const output = generator(ast, {}, source);
    return output.code
}

文章中如有问题欢迎大家批评指正?。