React 脚手架项目,typescript,在vscode中进行调试,并重写console.log

使用create-react-app 脚手架创建的项目,一般默认是在chrom中进行调试,但是如果你想要在vscode中进行调试,就要做相应的配置,并且原有的日志功能也不是很完善,所以下面我们就想办法让React项目在vscode中进行调试,并且改进一下console.log的功能

React 脚手架项目,使用mock数据,模拟后端数据

  • 用脚手架创建项目并运行
  • 安装必要的插件
  • 配置.vscode/launch.json
  • 增强console.log

用脚手架创建项目并运行

首先使用create-react-app 脚手架创建一个react项目
打开控制台,并进入相应的目录,使用命令

npx create-react-app my-app --template typescript

项目名称 my-app 后面的参数–template typescript 让项目使用typescript
项目创建完成后,进入项目目录,运行

npm install

等待包安装完成后,运行

npm start

项目会自动编译,并运行在本地 localhost:3000
正常情况下,浏览器会自动打开这个地址,看到React的默认页面,这样项目就算是创建完成了

安装必要的插件

完成上面的一步后,项目只能在chrome中运行和调试,如果我们想要让项目在vscode中进行调试,就得在vscode中安装相应的插件
在这里插入图片描述
Debugger for Chrome

配置.vscode/launch.json

接下来配置launch.json
如果你没有配置过launch.json,那你切换到vscode的调试页,看到的页面应该是这样的
React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第1张图片
点击蓝色的文字 “创建 launch.json” 文字,
React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第2张图片
选择环境Chrome,就会自动为我们创建好 .vscode/launch.json 文件
原始内容一般是这样的

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome against localhost",
            "url": "http://localhost:8080",
            "webRoot": "${workspaceFolder}"
        }
    ]
}

在项目的根目录下会出现这个文件在这里插入图片描述
我们把里面的内容替换成这样

{
    "version": "0.2.0",
    "configurations": [{
        "type": "chrome",
        "request": "launch",
        "name": "Launch Chrome",
        "url": "http://localhost:3000", // 改为目标 url
        "webRoot": "${workspaceFolder}/src",
        "sourceMapPathOverrides": {
            "webpack:///src/*": "${webRoot}/*", 
        }
    }]
}

接下来就可以用vscode进行调试了

  1. 首先还是得用 npm start 命令,让项目先运行
    React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第3张图片
    运行成功后,先关闭窗口
  2. 这时启动vscode的调试功能 在vscdoe中按F5 或者是使用这个按钮
    React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第4张图片
    此时,chrome会自动打开另外一个窗口,运行我们的React项目

接下来我们在项目的App.tsx文件中加入一些语句,并设置断点
React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第5张图片
刷新一下刚刚打开的浏览器页面
React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第6张图片
已经成功进入断点, 可以控制单步运行,观察变量的值等等
React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第7张图片
chrome控制台中的日志信息
React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第8张图片
vscode调试控制台中的打印出来的信息
在这里插入图片描述
chrome中的打印日志 和 vscode中的打印日志,功能也都正常

增强console.log

我们在使用vscode调试的过程中,发现原有的console.log功能比较薄弱,接下来我们就想办法稍微增强下log的功能,为它添加时间,函数,文件名和行号的功能
还有另外一个痛点,我们开发阶段经常会写很多了log语句在代码中,方便我们进行调试,但是如果项目正式上线以后,会要求把log都删除掉,以免泄露过多的信息,这时候一个一个删除显示是比较麻烦的,
所以,我们实现2个功能
1 增加log的信息
2 生产环境下自动禁用输出功能

  1. 首先安装如下2个npm包
npm install source-map-support --save
npm install babel-plugin-source-map-support --save-dev

并且在项目某个文件中引入 import “source-map-support/register”
这两个插件的目的是为了让代码在使用 new Error() 获取错误堆栈的时候,正确得使用sourcemap,从而得到正确的源文件名和行号,而不是打包后的文件
如果不使用这两个包,那么在new Error()中获取到的堆栈信息,是经过webpack打包压缩后的文件信息,并不会还原成原始的ts文件信息
(ps: 但是在chrome控制台中输出的堆栈信息可以正确还原)

  1. 新建一个LogHelper.ts文件,我们在这里重写console.log
    我一般会把文件创建在src/utils目录下
    在这里插入图片描述
    文件内容如下
//引入source-map-support,babel-plugin-source-map-support插件
import "source-map-support/register";
import path from "path";
import moment from "moment";//好用的获取时间的包
export class LogHelper {
    static Init() {
        
        //重新console.log()
        let log = console.log;
        console.log = function (message: any, ...args: any[]) {
        	//如果是生产环境下,不打印任何内容
        	//create-react-app 这个脚手架生产的项目,
        	//默认情况下,生产环境下process.env.NODE_ENV = "production", 
        	//开发环境 process.env.NODE_ENV = "development"
            if (process.env.NODE_ENV === "production") {
                return;
            }
            let stackInfoStr = LogHelper.stackInfo();
            //console.log()是可以控制输出内容的颜色的,这样的格式
            //console.log("%c这是要打印的内容","color:blue")
            //这里将时间戳,行数等信息打印成不同的颜色,内容为默认的白色
            let info = `%c[${moment().format("YYYY-MM-DD HH:mm:ss.SSS")}][log][${stackInfoStr.file}:${stackInfoStr.line} (${stackInfoStr.method})] %c`;
            log(info, "color: #48d1cc", "color: white", message, ...args);
        };

		//重新console.info()
        let loginfo = console.info;
        console.info = function (message: any, ...args: any[]) {
            if (process.env.NODE_ENV === "production") {
                return;
            }
            let stackInfoStr = LogHelper.stackInfo();
            let info = `%c[${moment().format("YYYY-MM-DD HH:mm:ss.SSS")}][info][${stackInfoStr.file}:${stackInfoStr.line} (${stackInfoStr.method})] %c`;
            loginfo(info, "color: #3ebe3e", "color: white", message, ...args);
        };

		//重新console.warn()
        let warn = console.warn;
        console.warn = function (message: any, ...args: any[]) {
            if (process.env.NODE_ENV === "production") {
                return;
            }
            let stackInfoStr = LogHelper.stackInfo();
            let info = `%c[${moment().format("YYYY-MM-DD HH:mm:ss.SSS")}][warn][${stackInfoStr.file}:${stackInfoStr.line} (${stackInfoStr.method})] %c`;
            warn(info, "color: #dbd172", "color: #dbd172", message, ...args);
        };

		//重新console.error()
        let error = console.error;
        console.error = function (message: any, ...args: any[]) {
        	//如果要在生产环境下仍然打印error信息,则把这里的if判断去掉
            if (process.env.NODE_ENV === "production") {
                return;
            }
            let stackInfoStr = LogHelper.stackInfo();
            //error默认就是红色,如果特意指定颜色反而会变成白色的,不知道为什么
            let info = `[${moment().format("YYYY-MM-DD HH:mm:ss.SSS")}][error][${stackInfoStr.file}:${stackInfoStr.line} (${stackInfoStr.method})] `;
            error(info, message, ...args);
        };
    }
	
	//通过这个函数,来获取打印内容所在的文件,函数和行号
	//你可以使用下 console.log(new Error()) 来试验下,看下打印出来的内容,就是通过这个方法获取到文件信息的
    static stackInfo(num: number = 0) {
        var stackReg = /at\s+(.*)\s+\((.*):(\d*):(\d*)\)/i;
        var stackReg2 = /at\s+()(.*):(\d*):(\d*)/i;
        var stacklist = new Error().stack.split("\n").slice(3);//获取堆栈信息,其中包含文件,函数和行号
        var s = stacklist[num];
        var sp = stackReg.exec(s) || stackReg2.exec(s);
        var data: any = {};
        if (sp && sp.length === 5) {
            data.method = sp[1];
            data.path = sp[2];
            data.line = sp[3];
            data.pos = sp[4];
            data.file = path.basename(data.path);
        }
        return data;
    }
}

文件中我直接重写了console.log console.info console.warn console.error4个方法,如果你还有其他的打印方法需要用到,也可以这样来重写.
主要需要注意的点已经写在注释中了

  1. 在项目最开始的地方调用 LogHelper.Init() 我直接写在项目入口处 index.tsx中
    React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第9张图片
    然后在App.tsx中测试一下
    React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第10张图片
    按照之前的测试方式开始调试
    这是在chrome中的打印效果
    React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第11张图片
    这是在vscode中的打印效果
    React 脚手架项目,typescript,在vscode中进行调试,并重写console.log_第12张图片
    json对象,数组等都还能够正常显示
    美中不足的是
    1 打印内容后面默认的调用位置只能显示我LogHelper中重新打印函数的地方,不能显示我书写console.log的实际位置,不过好在这个内容已经在打印内容的头部正确显示了.
    2 在vscode的打印信息中,无法显示warn 和 error 的堆栈信息
    如果有哪位小伙伴知道如何解决以上两个问题,也请告诉我一下

项目正常build打包以后,默认process.env.NODE_ENV 这个变量会变成 “production”,因此在实际部署项目时,就不会再打印任何内容了

你可能感兴趣的:(nodejs,react,javascript,reactjs)