Skip to main content

· 2 min read
fengjutian

js日志

type LoggerConfigType = {
// 命名空间
namespace?: string
}

/**
* 拦截器函数类型
*/
type InterceptorFuncType = (config: LoggerConfigType) => void

const enum LogLevel {
Log, // 普通日志
Warning, // 警告日志
Error, // 错误日志
}

const __DEV__ = import.meta.env.MODE
const Styles = ['color: green;', 'color: orange;', 'color: red;']
const Methods = ['info', 'warn', 'error'] as const

class Logger {
/** 命名空间(scope),用于区分所在执行文件 */
private beforeFuns: Array<InterceptorFuncType> = []
private afterFuns: Array<InterceptorFuncType> = []
private config: LoggerConfigType = {}

constructor(namespace = 'unknown') {
this.config.namespace = `[${namespace}]`
}
/**
* 创建新的 Logger 实例
*
* @param namespace 命名空间
* @returns Logger
*/
public create(namespace = 'unknown') {
return new Logger(namespace);
}

private _log(level: LogLevel, args: unknown[]) {
if (__DEV__ !== 'development') return
this.beforeFuns.forEach(func => func(this.config))
console[Methods[level]](`%c${this.config.namespace}`, Styles[level], ...args)
}

private addInterceptor(func: InterceptorFuncType, isBefore = true) {
if(typeof func !== 'function'){
return this.error('拦截器函数不符合规范')
}

if(isBefore){
this.beforeFuns.push(func)
}

this.afterFuns.push(func)
return this
}

// 日志打印之前的拦截器参数
public addBeforeFunc(func: InterceptorFuncType) {
this.addInterceptor(func)
return this
}

// 日志打印之后的拦截函数
public addAfterFunc(func: InterceptorFuncType) {
this.addInterceptor(func, false)
return this
}

/**
* 打印输出信息 🐛
*
* @param args 任意参数
*/
public info(...args: unknown[]) {
this._log(LogLevel.Log, args)
return this
}

/**
* 打印输出警告信息 ❕
*
* @param args 任意参数
*/
public warn(...args: unknown[]) {
this._log(LogLevel.Warning, args)
return this
}

/**
* 打印输出错误信息 ❌
*
* @param args 任意参数
*/
public error(...args: unknown[]) {
this._log(LogLevel.Error, args)
return this
}

/**
* 设置命名空间(日志前缀)
* @param namespace
*/
public setNamespace(namespace = '') {
this.config.namespace = `[${namespace}]`
return this
}

/**
* 远程上报
*/
public reportLog() {
this.info() // 用于在本地输出
}
public reportEvent() {
this.info()
}
public reportException() {
this.error()
}
}

export default new Logger()