vue中重写并自定义console.log

0. 背景

vue2项目中自定义console.log并输出文件名及行、列号

1. 实现

1.1 自定义console.log

在这里插入图片描述

export default {
  // 输出等级: 0-no, 1-error, 2-warning, 3-info, 4-debug, 5-log
  level: 5,
  // 输出模式: 0-default, 1-normal, 2-random
  mode: 1,
  // 是否输出图标
  hasIcon: false,
  // 是否在vue内使用
  isVue: true,
  // 是否打印函数名和所在文件行号
  isPrintLine: true,
  // 图标
  icons: ['🌵', '🎍', '🐾', '🌀', '🐚', '🥝', '🥜', '🥕', '🥒', '🌽', '🍒', '🍅', '🍑', '🍋', '🍈', '🌶', '🌰', '🍠', '🍆', '🍄', '🍐', '🍌', '🍍', '🍇', '🍏', '🍓', '🍎', '🍊', '🐴', '🐗', '🦄', '🐑', '🐶', '🐔', '🐼', '🐒', '🌝', '💄', '💋', '👠', '👗', '👙', '🧣', '🍰', '🍭', '🍳', '🎄', '🎱', '⚽', '🏀', '🎵', '🚄', '⭕', '❌', '❓', '❗', '💯'],
  // 标准颜色
  colors: {
    error: '#f7630c',
    warning: '#ca5010',
    info: '#0078d7',
    debug: '#13a10e',
    log: '#1f1f1f'
  },
  // 获取随机图标
  randomIcon: function () {
    return this.icons[Math.floor(Math.random() * this.icons.length)]
  },
  // 获取随机颜色
  randomColor: function () {
    const r = Math.floor(Math.random() * 256)
    const g = Math.floor(Math.random() * 256)
    const b = Math.floor(Math.random() * 256)
    // 返回随机生成的颜色
    return `rgb(${r}, ${g}, ${b})`
  },
  // 默认打印
  printDefault: function (tag, args) {
    console.log(tag, ...args)
  },
  // 标准打印
  printNormal: function (tag, args) {
    console.log(`%c ${tag} : `, `color: ${this.colors[tag]}`, ...args)
  },
  // 随机打印
  printRandom: function (tag, args) {
    const icon = this.randomIcon()
    const bgColor = this.randomColor()
    const color = this.randomColor()
    console.log(`%c ${icon}`, `font-size:20px;background-color: ${bgColor};color: ${color};`, tag + ' : ', ...args)
  },
  print: function (tag, args) {
    if (this.isPrintLine) {
      if (!this.isVue) {
        // 获取函数名和行号
        const err = new Error()
        // console.log(err.stack)
        const stack = err.stack.split('\n').slice(3).map(line => line.trim())
        // console.log(stack)
        const caller = stack[0].match(/at (.+) \(/) ? stack[0].match(/at (.+) \(/)[1] : stack[0].match(/at (.+):\d+:/)[1]
        const fileLine = stack[0].match(/\(.*\/(.+)\)/) ? stack[0].match(/\(.*\/(.+)\)/)[1] : stack[0].match(/(\d+:\d+)/)[1]
        // console.log(`${caller} (${fileLine}):\n`)

        args.shift(`[${caller} (${fileLine})]\n`)
      } else {
        args.shift()
      }
    } else {
      if (this.isVue) {
        args.shift().shift()
      }
    }

    switch (this.mode) {
      case 0: {
        this.printDefault(tag, args)
        break
      }
      case 1: {
        this.printNormal(tag, args)
        break
      }
      case 2: {
        this.printRandom(tag, args)
        break
      }
    }
  },
  error: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'error'
      if (this.level >= 1) {
        // oriLogFunc.call(console, 'error : ', args)
        this.print(tag, args)
      }
    }
  })(console.log),

  warning: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'warning'
      if (this.level >= 2) {
        // oriLogFunc.call(console, 'warning : ', args)
        this.print(tag, args)
      }
    }
  })(console.log),

  info: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'info'
      if (this.level >= 3) {
        // oriLogFunc.call(console, 'info : ', args)
        this.print(tag, args)
      }
    }
  })(console.log),

  debug: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'debug'
      if (this.level >= 4) {
        // oriLogFunc.call(console, 'debug : ', ...args)
        this.print(tag, args)
      }
    }
  })(console.log),

  log: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'log'
      if (this.level >= 5) {
        // oriLogFunc.call(console, 'log : ', ...args)
        this.print(tag, args)
      }
    }
  })(console.log)
}

1.2 webpack记录行号

添加自定义loader

在这里插入图片描述

module.exports = function (content) {
  content = content.toString('utf-8')
  if (this.cacheable) this.cacheable()
  const { name = ['this.\\$iceLog.log'] } = this.query.config || {}
  const fileName = this.resourcePath.replaceAll('\\', '/').match(/(?<=\/)(src.*)/gm)[0]
  content = content
    .split('\n')
    .map((line, row) => {
      let loggerName = name[0]
      for (let i = 1; i < name.length; i++) {
        loggerName += '|' + name[i]
      }
      const re = new RegExp(`(${loggerName})\\((.*?)\\)`, 'g')
      let result
      let newLine = ''
      let cursor = 0
      while ((result = re.exec(line))) {
        const col = result.index
        newLine += line.slice(cursor, result.index) + `${result[1]}('[${fileName}:${row + 1}:${col + 1}]\\n', ` + result[2] + ')'
        cursor += col + result[0].length
      }
      newLine += line.slice(cursor)
      return newLine
    })
    .join('\n')

  return content
}
module.exports.raw = true

1.3 配置loader

修改vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
  chainWebpack: config => {
    // config.devtool('eval-cheap-module-source-map')
    config.module
      .rule('vue')
      .use('vue-loader')
      .end()
      .rule('log-lineno')
      .use('./loaders/log-lineno.loader')
      .loader('./loaders/log-lineno.loader')
      .options({
        config: {
          name: [
            'this.\\$iceLog.error',
            'this.\\$iceLog.warning',
            'this.\\$iceLog.info',
            'this.\\$iceLog.debug',
            'this.\\$iceLog.log'
          ]
        }
      })
      .end()
  }
})

2. 测试

  created () {
    this.$iceLog.log(123)
    this.$iceLog.error(1, 2, 3, 4)
  },

在这里插入图片描述

3. 问题

3.1 .vue文件被编译多次,自定义log会输出两个目录

在这里插入图片描述
解决:
在自定义函数中移除一个参数:

在这里插入图片描述

x. 参考

  1. 重写并自定义console.log()输出样式
  2. 巧用 webpack 在日志中记录文件行号
  3. vue webpace相关
  4. Vue2工程化 webpack配置 loader插件
  5. webpack初学者看这篇就够了
  6. 你了解webpack中配置的loader的执行顺序吗?
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,您遇到的问题很可能是跨域问题导致的。在浏览器,如果前端JavaScript代码尝试从一个域名或端口号发送请求到另一个域名或端口号,那么浏览器通常会阻止这个请求,从而导致Network Error错误。 为了解决这个问题,您可以尝试在后端服务器设置CORS头,或者在前端Vue应用程序使用代理来发送请求。 方法一:在后端服务器设置CORS头 在您的Node.js后端服务器应用程序,您可以使用cors模块来设置CORS头。例如: ```javascript const express = require('express') const cors = require('cors') const app = express() app.use(cors()) // ...其他的路由和间件 app.listen(8010, () => { console.log('Server started on port 8010') }) ``` 这里的`app.use(cors())`会将CORS头添加到所有的响应,从而允许前端应用程序在8080端口上发送跨域请求。配置完成后,您可以在前端Vue应用程序使用如下代码来发送请求: ```javascript axios.get('http://192.168.43.225:8010/pmsservice/admin/getAllAdmin') .then(response => { console.log('请求成功了',response.data) }) .catch(error => { console.log('请求失败了',error.message) }) ``` 方法二:在前端Vue应用程序使用代理 在您的Vue应用程序的`vue.config.js`文件,您可以使用代理来转发请求。例如: ```javascript module.exports = { devServer: { proxy: { '/api': { target: 'http://192.168.43.225:8010', changeOrigin: true, pathRewrite: { '^/api': '' } } } } } ``` 这里的`/api`是您在Vue应用程序发送请求的API路径前缀。`target`是您要代理的后端服务器的地址和端口号。`changeOrigin`设置为`true`意味着将请求头的Host值设置为目标URL的Host值。`pathRewrite`是用来重写请求路径的,这里的设置是将请求路径的`/api`前缀替换为空字符串,以便正确匹配后端服务器的API路径。 配置完成后,您可以在前端Vue应用程序使用如下代码来发送请求: ```javascript axios.get('/api/pmsservice/admin/getAllAdmin') .then(response => { console.log('请求成功了',response.data) }) .catch(error => { console.log('请求失败了',error.message) }) ``` 希望这些方法能够帮助您解决问题。如果您有任何其他问题,请随时问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值