5分钟教你使用 console.log 输出五彩斑斓的黑

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 5分钟教你使用 console.log 输出五彩斑斓的黑

前言

image.png

console.log 对一个前端人,那是在熟悉不过了。我们最经常使用它在控制台输出信息然后进行代码调试,你肯定会发现输出的信息的颜色永远是黑色,当然还有一种我们最不喜欢的颜色 -- 红色,一旦出现了就意味BUG出现了。本文教你如何用 console 在控制台输出五颜六色的信息。



console.log 输出单色的信息

实现起来非常简单,就是 console[1] 能够解析占位符,总的就支持 5 个占位符 %o%s%s%f%c


其中 %c 指令将 CSS 样式应用于控制台输出,指令前的文本不会受到影响,但指令后的文本将使用参数中的 CSS 声明进行样式设置。


比如想在控制台输出123456,其中456的颜色是红色的,可以在控制台中输入以下代码

console.log('123%c456','color: red;')

image.png

从上图中可以看到,我们的尝试是有效的,并且表现完全符合预期。


把上面用法封装一下,形成一个“语法糖”,实现如下:

const red = (str)=>{
  console.log(`%c${str}`,'color: red')
}
red('Hello world!')


可以直接复制以上代码到控制台中执行,看是不是效果一样。red 方法就是一个在控制台输出蓝色的信息的语法糖。

其它 4 个占位符,可以翻阅 mozilla console[2] 了解哈。



更灵活的调用 console 方法

通过观察上面的用法,我们发现如果我们需要给同一个字符串添加更多的 CSS 效果,我们需要编辑 log 的第二个参数,而如果需要把两个有颜色的字符串拼接到一起,则需要修改第一参数,并且添加一个第三参数。

console.log(`%c123%c456`,'color: blue;','color: green;')

image.png


如果再继续拼接的话,那传入参数更多。在传入参数不确定的时候,我们可以使用 arguments 来获取传入参数,使用 ES6 语法的话,只需要写解构就行。

const log = (...args)=>{
    console.log.apply(void 0, args);
}



console.log 输出多色的信息

上面实现了单色的信息,那么多色的信息如何实现呢?console.log 在第一个参数后,还可以接受多个参数,每个参数可以给对应的信息设置不同的颜色,具体实现如下:

console.log('%c123%c456','color: blue','color: green')

image.png

那如何将 console.log 输出多色的信息封装一下,形成一个"语法糖"呢?


可以这么做,把一个信息拆分成多段,再对应设置不同的颜色,再组合起来 console.log 输出。

比如把 123456 拆分成 123456,再对应不同的颜色,数据如下所示:

['%c123','color: blue']
['%c456','color: green']


写一个 add 方法将上面数据拼接成 ['%c123%c456','color: red','color: blue'] ,然后利用 apply 调用 console.log ,如下所示:

console.log.apply(void 0, ['%c123%c456','color: blue','color: green']);


复制以上代码到控制台中执行,效果如下图所示:

image.png


下面来实现一下 add 方法,并对 console.log 进行二次封装。

const _console = console;
const createlog = (util) => (...args) => {
  const fun = _console[util] ? _console[util] : _console.log;
  fun.apply(void 0, args);
};
const add = (...arr) => {
    let fi = [[]];
    for (let key = 0; key < arr.length; key++) {
      const [first, ...other] = arr[key];
      fi[0] += first;
      fi = fi.concat(other);
    }
    return fi;
  };
createlog('log')(...add(['%c123','color: blue',],['%c456','color: green']));


复制以上代码到控制台中执行,看一下效果,效果如下图所示:

image.png



预设一些颜色值

我们将常用到的一些颜色值,都内置封装一下,方便使用,将上面实现的 red 方法的改造成按这样 chalk.log(chalk.red(123)) 调用。

const _console = console;
const createlog = (util) => (...args) => {
  const fun = _console[util] ? _console[util] : _console.log;
  fun.apply(void 0, args);
};
const add = (...arr) => {
    let fi = [[]];
    for (let key = 0; key < arr.length; key++) {
      const [first, ...other] = arr[key];
      fi[0] += first;
      fi = fi.concat(other);
    }
    return fi;
  };
const chalk = {
  log:createlog('log')
};
const color = {
  black: '#00000',
  red: '#FF0000',
  green: '#008000',
  yellow: '#FFFF00',
  blue: '#0000FF',
  magenta: '#FF00FF',
  cyan: '#00FFFF',
  white: '#FFFFFF',
};
Object.keys(color).forEach((key) => {
  chalk[key] = (str) => {
    // 用户会有两种用法 chalk.red('1231')
    if (typeof str === 'string' || typeof str === 'number') {
      return [`%c${str}`, `color:${color[key]}`];
      }
    // 用户第二种用法 chalk.red(chalk.bold('123'))
    for (let i = 1; i < str.length; i++) {
      str[i] += `;color:${color[key]}`;
    }
    return str;
  };
});
chalk.log(...add(
  chalk.black('black'),
  chalk.red('red'),
  chalk.green('green'),
  chalk.yellow('yellow'),
  chalk.blue('blue'),
  chalk.magenta('magenta'),
  chalk.cyan('cyan'),
  chalk.white('white')
  )
)


复制以上代码到控制台中执行,看一下效果,效果如下图所示:

image.png



增加背景色

通过观察我们发现背景色的方法名,其实就是颜色方法首字母大写再增加 bg 前缀。

简单的修改上面的方法实现

Object.keys(color).forEach((key) => {
    colorUtils[key] = (str: string | string[]) => {
      // 用户会有两种用法 chalk.red('1231')
      if (typeof str === 'string' || typeof str === 'number') {
        return [`%c${str}`, `color:${color[key]}`];
      }
      // 用户第二种用法 chalk.red(chalk.bold('123'))
      for (let i = 1; i < str.length; i++) {
        str[i] += `;color:${color[key]}`;
      }
      return str;
    };
    colorUtils[`bg${firstToUpperCase(key)}`] = (str: string | string[]) => {
      if (typeof str === 'string' || typeof str === 'number') {
        return [`%c${str}`, `padding: 2px 4px; border-radius: 3px; color: ${key === 'white' ? '#000' : '#fff'}; font-weight: bold; background:${color[key]};`];
      }
      for (let i = 1; i < str.length; i++) {
        str[i] += `;padding: 2px 4px; border-radius: 3px; font-weight: bold; background:${color[key]};`;
      }
      return str;
    };
  });



给日志分级别

为了进一步对日志输出作出更加合理的管控,也为了提供更多的默认颜色输出,因此我们给日志输出划分等级。

const colorHash = {
    log: 'black',
    wait: 'cyan',
    error: 'red',
    warn: 'yellow',
    ready: 'green',
    info: 'blue',
    event: 'magenta',
};


使用这些分级会默认给输出日志添加前缀,如 [Error],后面的颜色是默认颜色。

let chalk = {};
if (!window.chalk) {
  const _console = console;
  const color = {
    black: '#000000',
    red: '#FF0000',
    green: '#008000',
    yellow: '#FFFF00',
    blue: '#0000FF',
    magenta: '#FF00FF',
    cyan: '#00FFFF',
    white: '#FFFFFF',
  };
  const add = (...arr) => {
    let fi = [
      []
    ];
    for (let key = 0; key < arr.length; key++) {
      const [first, ...other] = arr[key];
      fi[0] += first;
      fi = fi.concat(other);
    }
  return fi;
  };
  const createlog = (util) => (...args) => {
    const fun = _console[util] ? _console[util] : _console.log;
    fun.apply(void 0, args);
  };
  const colorUtils = {
    bold: (str) => {
      if (typeof str === 'string' || typeof str === 'number') {
        return `${str};font-weight: bold;`;
      }
      for (let key = 1; key < str.length; key++) {
        str[key] += `;font-weight: bold;`;
      }
      return str;
    }
  };
  const colorHash = {
    log: 'black',
    wait: 'cyan',
    error: 'red',
    warn: 'yellow',
    ready: 'green',
    info: 'blue',
    event: 'magenta',
  };
  const createChalk = (name) => (...str) => {
    if (typeof str[0] === 'object') {
      createlog(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name "colorHash[name]")}] `)), ...str));
      return;
    }
    let strArr = str;
    if (typeof str === 'string' || typeof str === 'number') {
      strArr = colorUtils[colorHash[name]](str "colorHash[name]");
    }
    createlog(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name "colorHash[name]")}] `)), strArr));
  };
  const chalk = {};
  Object.keys(colorHash).forEach(key => {
    chalk[key] = createChalk(key);
  });
  const firstToUpperCase = (str) => str.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase());
  Object.keys(color).forEach(key => {
    colorUtils[key] = (str) => {
      if (typeof str === 'string' || typeof str === 'number') {
        return [`%c${str}`, `color:${color[key]}`];
      }
      for (let i = 1; i < str.length; i++) {
        str[i] += `;color:${color[key]}`;
      }
      return str;
    };
    colorUtils[`bg${firstToUpperCase(key)}`] = (str) => {
    if (typeof str === 'string' || typeof str === 'number') {
       return [`%c${str}`, `padding: 2px 4px; border-radius: 3px; color: ${key === 'white' ? '#000' : '#fff'}; font-weight: bold; background:${color[key]};`];
    }
     for (let i = 1; i < str.length; i++) {
        str[i] += `;padding: 2px 4px; border-radius: 3px; font-weight: bold; background:${color[key]};`;
     }
     return str;
   };
  });
  window.chalk = {
    add,
    ...chalk,
    ...colorUtils,
  };
}
chalk = window.chalk;
chalk.log('log');
chalk.error('error');
chalk.warn('warn')



自定义定制函数

熟练的上述的方法之后,你就可以随意的添加你需要的函数了,比如常见的打印框架的版本号。

const hello = (title: string, version: string) =>
      createlog('log')(
        `%c ${title} %c V${version} `,
        'padding: 2px 1px; border-radius: 3px 0 0 3px; color: #fff; background: #606060; font-weight: bold;',
        'padding: 2px 1px; border-radius: 0 3px 3px 0; color: #fff; background: #42c02e; font-weight: bold;',
      );
hello('Malita','0.0.6');

image.png


比如打印图片

const image = (img: string) => createlog('log')(`%c `, `font-size: 1px;
padding: 100px 100px;
background-image: url(${img});
background-size: contain;
background-repeat: no-repeat;
color: transparent;`);
image('https://logo.png')

image.png

当然你也可以输出动图。只要你熟练掌握了这些方法,你就可以随意的发挥你的创意。



灵感来源

以上实现的灵感来源于一个很流行的 node 控制台美化仓库,chalk[3],它在 GitHub 上拥有 18.3k 的 star。

import chalk from 'chalk';
console.log(chalk.blue('Hello world!'));

image.png


在项目中使用

为了方便大家和我自己使用,我将这个功能发布到了 npm 上,你可以在你的项目中使用。

npm i @alita/chalk
import chalk from '@alita/chalk';
window.alitadebug = true;
chalk.hello('Malita','0.0.6');
// 或者
import '@alita/chalk';
window.alitadebug = true;
window.chalk.hello('Malita','0.0.6');


我增加了一个日志开关 window.alitadebug = true;,好处就是部署上线的代码,正常情况下不打印日志,如果出现错误需要定位代码,可以直接通过控制台中输入 window.alitadebug = true; 来开启。

源码开源[4]

21天挑战手写前端框架系列[5]

感谢阅读,如果你觉得这个东西很有趣,或者你有好的创意,欢迎在评论区和我互动。



参考资料

[1]

console: https://developer.mozilla.org/en-US/docs/Web/API/console#examples

[2]

mozilla console: https://developer.mozilla.org/en-US/docs/Web/API/console#examples

[3]

chalk: https://github.com/chalk/chalk

[4]

源码开源: https://github.com/alitajs/alita/tree/master/packages/chalk

[5]

21天挑战手写前端框架系列: https://juejin.cn/column/7084812367116107789

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
5月前
|
机器学习/深度学习 JavaScript 前端开发
你不知道的console.log用法
在JavaScript中,使用`console.log()`时,通过大括号能显示变量名和值。`console.table(data, columns)`用于格式化打印表格。常用方法包括:`console.log()`
49 0
|
6月前
|
JavaScript 前端开发 开发者
使用`console.log()`查看运行结果非常简单
【4月更文挑战第18天】使用`console.log()`查看运行结果非常简单
274 1
|
移动开发
5分钟教你使用 console.log 管理你的输出日志
5分钟教你使用 console.log 管理你的输出日志
134 0
控制台输出信息console.log()的用法总结
控制台输出信息console.log()的用法总结
200 0
|
算法
已知x=10*log10(S/N)-10*log10(S/(N+k*N)),输入任意x输出10*log10(k)的值并打印出来
已知x=10*log10(S/N)-10*log10(S/(N+k*N)),输入任意x输出10*log10(k)的值并打印出来
105 0
console.log控制台里怎么输出图片
console.log控制台里怎么输出图片
154 0
console.log控制台里怎么输出图片
|
Java
Log4j中禁止打印某一类日志
目前我们在项目中使用的日志管理大多都是 Log4j ,它确实让我们对日志的管理更加的方便,快捷
605 0
Log4j中禁止打印某一类日志
|
JavaScript C语言
console.log(a + a++ * ++ a)到底输出什么?
前言 有些小伙伴可能看到这道题目就已经蒙圈了!甚至可能看不懂这道题目在干什么。其实这是一道比较考察基础的面试题,当你明白原理之后,你可能会感觉这道题也就那么回事,但是如果你没有思绪,那你可能觉得这道题很难。 今天我们就来彻底看看这到底在做什么妖!
511 0
console.log(a + a++ * ++ a)到底输出什么?
|
Web App开发 XML JavaScript
Console 3000字完整指南,让你不只会用console.log !
Console 3000字完整指南,让你不只会用console.log !
Console 3000字完整指南,让你不只会用console.log !
7 个让你的 console.log() 输出脱颖而出的提示和技巧(02)
7 个让你的 console.log() 输出脱颖而出的提示和技巧
325 0
7 个让你的 console.log() 输出脱颖而出的提示和技巧(02)