npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@xinmier/loggers

v2.7.0

Published

辛米尔网页编程工具集·控制台消息机集。

Downloads

19

Readme

辛米尔网页编程工具集·控制台消息机集

npm 包

npm 包之名称

@xinmier/loggers

npm 包之主页

https://www.npmjs.com/package/@xinmier/loggers

概述

总述

@xinmier/loggers 是一个 npm 包,称“控制台消息机集”。下称【本软件】。

本软件是一种编程元件,面向网页开发人员或 Nodejs 程序员,而非最终用户。

开发人员在网页控制台(或令 Nodejs 程序在系统终端)中打印【消息】时,常有如下需求:

  • 需为【消息】添加固定的【前缀】。且不同模块,其【消息】之【前缀】亦不相同。

  • 需将一切【消息】划分出若干【等级】。又另设【等级控制量】,以求仅打印符合【等级要求】的【消息】。具体而言,若调高【等级控制量】,则在控制台打印的【消息】可能增多;反之。

采用本软件,即可实现上述需要。

又,本品将消息分 1 ~ 5 五等。等级【高】者是“繁冗”、“啰嗦”或“旁枝末节”、“细致入微”的【消息】,等级【低】者是所谓“重要”的【消息】。

注:【消息等级】参数共有 6 种可能的值。其中包含 1 ~ 5 个【消息等级】,加上 0 值(代表不打印任何消息)。

【工厂函数】、【消息机集】与【消息机】

本品对外给出一个所谓【工厂函数】。调用【工厂函数】 1 次,产出 1 个【消息机集】;调用多次,产出多个互相独立的【消息机集】。

产生的每一个所谓【消息机集】,携带若干(目前是 11 个)所谓【消息机】。凡【消息机】,大同小异。【消息机】均可用以代替 console.logconsole.debugconsole.warnconsole.error 四者, 但不替代其余诸如 console.infoconsole.group 等。

不妨将【消息机集】携带的 11 个【消息机】分为 3 类:

  1. 〖日志类〗,或称 log 类。共 7 个。均用于替代 console.logconsole.debug 二者。

    凡〖日志类〗【消息】,均是有【消息等级】的。仅符合【等级要求】的〖日志类〗【消息】会打印,其余会被忽略。

  2. 〖警告类〗,或称 warn 类。共 2 个。均用于替代 console.warn

    凡〖警告类〗【消息】均无【等级】。换言之,〖警告类〗【消息】一律打印,不可忽略。

  3. 〖报错类〗,或称 error 类。共 2 个。均用于替代 console.error

    凡〖报错类〗【消息】均无【等级】。换言之,〖报错类〗【消息】一律打印,不可忽略。

以下是【工厂函数】、【消息机集】与【消息机】之间的派生关系(或者说粗略的看作包含关系),以辅助理解:

【工厂函数】 1 次制造 1 个【消息机集】。

1 个【消息机集】 包含 11 个【消息机】,以及 1 个【等级裁决函数】。

可调用任意【消息机】以处理【消息】。
    注:
        所谓“处理”某【消息】,即指要么打印该【消息】,要么忽略该【消息】。
        故,调用任何【消息机】时,应将 1 则或若干则【消息】交付给它,供其“处理”。
        该【消息机】会依照在调用【工厂函数】时预设好的【等级标准】要求而动作,要么打印这些【消息】,要么略过这些【消息】。

可调用【等级裁决函数】,以获悉该组【消息机集】是否会打印特定【等级】的【消息】。

故而有以下假想的“等级”树:

此处“等级树”一词并不准确、达意。诸君领会精神即可。望能辅助理解、记忆。

- 工厂函数

    - 【消息机集】(目前含 11 枚消息机,以及一枚【等级裁决函数】)

        - 【等级裁决函数】,返回一个布尔值。
            - 外界调用该【等级裁决函数】,可获悉该组【消息机集】是否会打印特定【等级】的【消息】。

        - 【消息机 1】 (其属性名为 `log` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 或 console.debug 1 次。

        - 【消息机 2】 (其属性名为 `logLevel1` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 1 次。

        - 【消息机 3】 (其属性名为 `logLevel2` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 1 次。

        - 【消息机 4】 (其属性名为 `logLevel3` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 1 次。

        - 【消息机 5】 (其属性名为 `logLevel4` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.debug 1 次。

        - 【消息机 6】 (其属性名为 `logLevel5` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.debug 1 次。

        - 【消息机 7】 (其属性名为 `logGroup` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 或 console.debug 若干次。
                注:在调用时给出的参数表中,每个数组代表一行,每行调用一次 console.log 或 console.debug 。

        - 【消息机 8】 (其属性名为 `warn` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.warn 1 次。

        - 【消息机 9】 (其属性名为 `warnGroup` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.warn 若干次。
                注:在调用时给出的参数表中,每个数组代表一行,每行调用一次 console.warn 。

        - 【消息机 10】 (其属性名为 `error` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.error 1 次。

        - 【消息机 11】 (其属性名为 `errorGroup` )
            - 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.error 若干次。
                注:在调用时给出的参数表中,每个数组代表一行,每行调用一次 console.error 。

消息【等级】系统的运作机制

如本文《总述》中所述,本软件将一切〖日志类〗【消息】划分出若干【等级】。又另设【等级控制量】,以仅打印符合【等级要求】的【消息】。

具体而言,若调高【等级控制量】,则在控制台打印的【消息】可能增多;反之。故而,在构建本软件的【消息机集】时,须给出所谓【允许打印的等级标准】,该标准不妨简称【等级标准】或【等级要求】。又,此所谓【等级标准】即为前述所谓【等级控制量】。凡构建出的【消息机】,其〖日志类〗方法函数处理〖日志类〗【消息】时,一律遵照该【等级标准】;但其〖警告类〗和〖报错类〗方法函数,则不受【等级标准】之影响。

调用某〖日志类〗【消息机】时,自当给出【消息】以供其处理(即打印该【消息】或略去该【消息】)。不难理解,此时须同时指明该【消息】之【等级】。

又,默认的规则是,若【消息】之【等级】小于或等于【允许打印的等级标准】,则该【消息】被打印出来,否则该【消息】被略去。

又,程序员亦可给出所谓【等级裁决函数】,而非给出【允许打印的等级标准】。若给出了【等级裁决函数】,则任何〖日志类〗【消息机】是否打印【消息】,取决于该【等级裁决函数】的【返回值】。具体而言,于任何〖日志类〗【消息】,凡【等级裁决函数】处理其【等级】后返回 true 者,该【消息】会被打印;反之,若【等级裁决函数】处理其【等级】后返回 false ,则该【消息】会被略去。

针对【消息】内容构建之性能优化举措

初期之考虑

某些【消息】之内容颇为繁复。

例如,程序员可能按需打印某非常复杂之【对象】,或巨大的【列表(Array)】,以检视其程序运转之细节。然而,此类消息可能因不满足【等级要求】而被略过。

于此情形,若不采取任何特别措施,则即使该【消息】之【等级】确不满足【等级要求】,或确被【等级裁决函数】裁定为“应略去”,但用以构建该繁复【消息】内容的代码早已运转完毕。换言之,用以构建这些【消息】内容的计算功,会因相关【消息】被裁定为“应略去”而白白浪费掉。此种浪费积少成多,或颇为可观。故,应省则省。

实践证明当下举措未显见裨益

然而,本工具之源代码库中随附了一个简陋的所谓“性能对比.ts”,其运行结果显示,采用函数按需构建须打印的内容,并不比看似“提前”构建须打印内容的方式耗时明显更短,偶然反而耗时更长。也许因为 JavaScript 语言解释器解释函数体本身耗费的时间已然不菲,且超过打印动作之耗时。亦可能因为该简陋的测试代码中的打印任务过轻,不足以体现采用函数方式的真正优势。

尽管上述简陋的性能测试工具令“可以采用函数来临时生成须打印内容”的设计显得多此一举,我也不打算取消该设计。毕竟采用该设计时,并没有负面影响。

总之,上文假想的“或颇为可观”并不成立。改用函数临时按需生成须打印之内容,未显见裨益。

附:该《性能对比.ts》即可以运行在 Nodejs 命令行环境,亦可运行在浏览器环境。

  • 运行在 Nodejs 命令行环境的做法:

    npm  run  bench-mark-in-nodejs
  • 运行在浏览器环境的做法:

    1. 先要在命令行环境构建出适合浏览器环境运行的代码。特别是,代码须为 JavaScript 而不是 TypeScript 。故而,请先在命令行环境中执行下方命令:

      npm  run  build-test-of-bench-mark-in-html
    2. 然后,启动一个 Http 服务程序,来伺服 ./测试集 这一文件夹。又,为便于举例,假定你配置的站点为 http://localhost:11094

      你采用 nginx 、 tomcat 、 IIS 之类的工具均可。如果你正在使用 VSCode 这款工具,那么不妨采用 VSCode 的 Expressjs 插件。 本工具之源代码库中的 VSCode 配置文件(settings.json)中已有现成的配置条目。

    3. 打开浏览器,浏览 http://localhost:11094/源/index.html 这一网址。

    4. 按键盘上的 F11 键,或按 Ctrl + Shift + i 组合键,来打开浏览器的“控制台”。在控制台中观察执行结果。

说回函数临时生成内容之细节

尽管采用函数的方法未显见裨益,但仍得以保留。以下是该设计之细节。

为求节省计算之功,本品自 v2.5.0 版始,视所有实参中“直接”给出的函数为所谓【消息内容生成器】。与本品之前的版本不同,在本品之新版中,这些【消息内容生成器】会被调用,而不是被 console.log 之类的原生函数打印出来。调用后,其【返回值】才作为【消息】内容。

所谓 “ 在实参中直接给出 ” ,如何理解?须知,凡诸【消息机】实参中的函数,可能存在于以下“位置”:

  1. 某函数(甲)自身即为【消息机】之某实参。凡此种函数,即是所谓“直接”给出的函数。【消息机】会调用它,并以其返回值作为【消息】内容。
  2. 某函数(甲)为【消息机】之某实参对象(乙)之方法函数。于此情形,【甲】视作【消息】内容的一部分。
  3. 某函数(甲)为【消息机】之某实参列表(Array)(乙)之成员。于此情形,【甲】视作【消息】内容的一部分。
  4. 某函数(甲)为某“直接”给出之函数(乙) 调用 后的【返回值】,或【返回值】的一部分。于此情形,产出的【甲】视作【消息】内容的一部分。

凡视为【消息】内容之部分的函数,【消息机】不会调用它。故而,一旦【消息】之【等级】满足要求,则 console.log 之类的原生函数会将前述函数(作为【消息】的一部分)打印出来。

又,已知〖警告类〗和〖报错类〗【消息】一律打印,不可略过,因此理论上不必为这类【消息机】设计【消息内容生成器】的逻辑。但,为求令一切【消息机】之行为相仿,遂令〖警告类〗和〖报错类〗【消息机】也可接受所谓“直接”给出的函数,作为【消息内容生成器】。

又见下例。

import { createXmeLoggers } from '@xinmier/loggers'


const xmeLoggers1 = createXmeLoggers({
    messagePrefix: '某某模块之名称',
})

xmeLoggers1.logLevel2(() => [ '某函数产出的消息内容' ])

xmeLoggers1.logGroup(2, () => [
    [ createMessageToPrintOfLevel(1) ],
    [ createMessageToPrintOfLevel(2) ],
    [ createMessageToPrintOfLevel(3) ],
    [ createMessageToPrintOfLevel(4) ],
    [ createMessageToPrintOfLevel(5) ],
], [
    {
        我乃复杂的对象: 1,

        我有不少属性: true,

        有些属性还挺复杂: {
            中华英雄谱: [
                '霍去病',
                '岳飞',
                '彭大元帅',
                '钱学森',
                '81192 王伟',
            ],
        },

        消息内容: [
            '我的“母对象”视作一则【消息】的一部分。',
            '首先,它是一个对象。',
            '又,它位于列表中而非由函数产生。故而它会过早构造。',
            '一旦本次打印被整个略过,则用以产生该对象的计算将是无用功,形成浪费。',
        ].join(''),

        我还有方法函数: () => Math.random().toFixed(8).slice(2),

        '须知,方法函数是视作【消息】内容的一部分的。它将被原封不动地打印常量,而不是被【消息机】调用。' () {
            // 今有雉兔同笼,上有三十五头,下有九十四足,问雉兔各几何?
            const 鸡兔共有头 = 35 // eslint-disable-line
            const 鸡兔共有脚 = 94 // eslint-disable-line
            return {
                鸡: 23,
                兔: 12,
            }
        },
    }
])

综上,简言之,有以下两点:

  1. 调用【工厂函数】时,须给出【等级标准】,或【等级裁决函数】。
  2. 调用〖日志类〗【消息机】来尝试打印【消息】时,须给这条【消息】自身的【等级】。【等级】合规,则该【消息】确实会打印;否则,该【消息】会被忽略。
  3. 〖警告类〗和〖报错类〗【消息】没有所谓【等级】。换言之, 〖警告类〗和〖报错类〗【消息】一律打印。
  4. 凡“直接”作为实参的函数,视作【消息内容生成器】,它们均会被调用。一切产出(即返回值)视作【消息】内容。

为不同模块设计不同的【消息前缀】

当应用程序较复杂时,为了指明消息所隶属的模块,程序员往往会在各消息中设计前缀。特定的模块中的消息,采用特定的、共同的前缀。由此,不同模块打印的消息易于区别、理解。

若运用本工具集,如何做到这一点呢?很简单,分别为每一个模块调用【工厂函数】一次,每次给定不同的消息前缀。即可。见下例。

// 源文件-1.js

import { createXmeLoggers } from '@xinmier/loggers'

const xmeLoggersOfModule1 = createXmeLoggers({
    // * * * * * * * * * * * * * * * * * * * *
    messagePrefix: '模块-1', // 本例之重点在此。
    // * * * * * * * * * * * * * * * * * * * *

    /**
     * 于本套【消息机集】,
     * 凡允许打印的【消息】,其【等级】不得高于 4 ,但可以等于 4 。
     */
    allowedLogMaxLevel_Or_LogLevelsTriage: 4,
})

console.log(xmeLoggersOfModule1.shouldLogLevel(3)) // 该语句打印出 true 。
// 源文件-2.js

import { createXmeLoggers } from '@xinmier/loggers'

const xmeLoggersOfModule2 = createXmeLoggers({
    // * * * * * * * * * * * * * * * * * * * *
    messagePrefix: '模块-2', // 本例之重点在此。
    // * * * * * * * * * * * * * * * * * * * *

    /**
     * 于本套【消息机集】,
     * 凡允许打印的【消息】,其【等级】须为 1 。
     */
    allowedLogMaxLevel_Or_LogLevelsTriage: 1,
})

console.log(xmeLoggersOfModule2.shouldLogLevel(3)) // 该语句打印出 false 。

用法(面向网页开发人员)

安装

在命令行环境中,cd 进入你的网页开发项目的文件夹,并执行以下命令:

npm  i  @xinmier/loggers

在代码中使用本工具集

本工具集面向网页开发人员。程序员在编写其代码时,可以采用本工具集。故下方所谓用法均系介绍在编程活动中如何采用本工具集。因此,所谓“用法”亦称“写法”。

简单示例

import {
    createXmeLoggers,
} from '@xinmier/loggers'




const xmeLoggersOfMyAppCoreModule = createXmeLoggers({
    /**
     * 假设有某某程序,其包含一个名为“核心模块”的模块。
     * 则,为该所谓“核心模块”专门设计的【消息机集】,
     * 其任何【消息】不妨配有如下【消息前缀】。
     */
    messagePrefix: '核心模块',

    /**
     * 于本套【消息机集】,
     * 凡允许打印的【消息】,其等级不得高于 3 ,但可以等于 3 。
     */
    allowedLogMaxLevel_Or_LogLevelsTriage: 3,
})



/**
 * 下方 `core` 即为设想的“某某程序的”所谓“核心模块”。
 * 假设该模块具备两个【方法函数】: `method1` 和 `method2` 。
 * 假设上述两个方法函数内若干处,须按需打印一些消息。
 */
export const core = {
    method1 (): void {
        xmeLoggersOfMyAppCoreModule.log(4, '该消息不会被打印', ',因为其等级为', 4, '超出了要求的 3 等级。')
        xmeLoggersOfMyAppCoreModule.logLevel5('该消息不会被打印', ',因为其等级为', 5, '超出了要求的 3 等级。')
    },

    method2 (): void {
        xmeLoggersOfMyAppCoreModule.log(2, '该消息会被打印,因为其等级为 2 。并未超出要求的 3 等级。')
        xmeLoggersOfMyAppCoreModule.logLevel1('该消息会被打印,因为其等级为 1 。并未超出要求的 3 等级。')

        const someEventDetails = { 肇: '老吴' }

        if (xmeLoggersOfMyAppCoreModule.shouldLogLevel(4)) {
            xmeLoggersOfMyAppCoreModule.log(4, '重大事件。细节如下:', { ...someEventDetails })
        } else {
            xmeLoggersOfMyAppCoreModule.log(1, '重大事件。')
        }
    },
}

完整的测试集

下方的代码主体等同于本软件配套的测试集的代码全文。仅删去了少了无关紧要的代码。

又,测试集文件为 ./测试集/index.ts

import {
    T_XmeLogLevel,
    createXmeLoggers,
} from '../yuan/index.js'



function createMessageToPrintOfLevel (level: T_XmeLogLevel) { return `应出现该句。此句【消息】之【等级】为 ${level} 。` }

const MESSAGE_TO_HIDE  = '!!!!!!!! 不应出现该句!'
const messageOfWarning = '故意警告一次!换言之,此警告并不意味着该测试用例结果不合预期。'
const messageOfError   = '故意报错一次!换言之,此报错并不意味着该测试用例结果不合预期。'

function createMessageLinesToPrint (category: '日志' | '警告' | '报错'): Array<Array<any>> {
    const heading = category === '日志' ? '应该出现的多行〖日志〗'
        : category === '警告' ? '多行〖警告〗'
            : '多行〖报错〗'

    return [
        [ `${heading}:`, '这是第', 1, '行。' ],
        [ `${heading}:`, '这是第', 2, '行。' ],
        [ `${heading}:`, '这是第(3)行。' ],
        [ `${heading}:`, '这是第四行。' ],
        [ `${heading}:`, '^ ^ ^ ^ ^ ^ ^ ^' ],
    ]
}

const MESSAGE_LINES_TO_HIDE: Array<Array<any>> = [
    [ '不应出现该多行消息!', '这是第', 1, '行。' ],
    [ '不应出现该多行消息!', '这是第', 2, '行。' ],
    [ '不应出现该多行消息!', '这是第(3)行。' ],
    [ '不应出现该多行消息!', '这是第四行。' ],
    [ '不应出现该多行消息!', '^ ^ ^ ^ ^ ^ ^ ^' ],
]



/* eslint-disable no-constant-condition */



// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

const xmeLoggers = createXmeLoggers({
    messagePrefix: '功能块甲',
    allowedLogMaxLevel_Or_LogLevelsTriage: 3,
})

xmeLoggers.log(0, MESSAGE_TO_HIDE)
xmeLoggers.log(1, createMessageToPrintOfLevel(1))
xmeLoggers.log(2, createMessageToPrintOfLevel(2))
xmeLoggers.log(3, createMessageToPrintOfLevel(3))
xmeLoggers.log(4, MESSAGE_TO_HIDE)
xmeLoggers.log(5, MESSAGE_TO_HIDE)

xmeLoggers.logLevel1(createMessageToPrintOfLevel(1))
xmeLoggers.logLevel2(createMessageToPrintOfLevel(2))
xmeLoggers.logLevel3(createMessageToPrintOfLevel(3))
xmeLoggers.logLevel4(MESSAGE_TO_HIDE)
xmeLoggers.logLevel5(MESSAGE_TO_HIDE)

/**
 * 【消息】是有【等级】的。
 * 下方第 1 个参数并不是数字。因此该组【多行消息】的【等级】为默认的 2 。
 * 下方第 2 个参数也不是数字。因此每行依照默认配置,缩进 4 个空格。
 */
xmeLoggers.logGroup(      ...createMessageLinesToPrint('日志'))

/**
 * 【消息】是有【等级】的。
 * 下方第 1 个参数 3 即代表该组【多行消息】的【等级】为 3 。
 * 下方第 2 个参数并不是数字。因此每行依照默认配置,缩进 4 个空格。
 */
xmeLoggers.logGroup(3,    ...createMessageLinesToPrint('日志'))

/**
 * 【消息】是有【等级】的。
 * 下方第 1 个参数 3 即代表该组【多行消息】的【等级】为 3 。
 * 下方第 2 个参数 3 代表每行缩进 3 个空格。
 */
console.log('注意:下面一组信息,将缩进明确配置为 3 个空格。')
xmeLoggers.logGroup(3, 3, ...createMessageLinesToPrint('日志'))

/**
 * 【消息】是有【等级】的。
 * 下方第 1 个参数 4 即代表该组【多行消息】的【等级】为 4 。
 * 特定于本例,该组【多行消息】并不会打印。因为等级 4 不满足条件。
 */
xmeLoggers.logGroup(4, ...MESSAGE_LINES_TO_HIDE)

/** 【警告】是没有所谓【等级】的。【警告】一律打印。 */
xmeLoggers.warn(messageOfWarning)

/** 【警告】是没有所谓【等级】的。【警告】一律打印。 */
xmeLoggers.warnGroup(...createMessageLinesToPrint('警告'))

/** 【报错】是没有所谓【等级】的。【报错】一律打印。 */
xmeLoggers.error(messageOfError)

/** 【报错】是没有所谓【等级】的。【报错】一律打印。 */
xmeLoggers.errorGroup(...createMessageLinesToPrint('报错'))



// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



const xmeLoggers = createXmeLoggers({
    messagePrefix: '功能块乙',
    allowedLogMaxLevel_Or_LogLevelsTriage: l => l === 4 || l === 1,
})

xmeLoggers.log(0, MESSAGE_TO_HIDE)
xmeLoggers.log(1, createMessageToPrintOfLevel(1))
xmeLoggers.log(2, MESSAGE_TO_HIDE)
xmeLoggers.log(3, MESSAGE_TO_HIDE)
xmeLoggers.log(4, createMessageToPrintOfLevel(4))
xmeLoggers.log(5, MESSAGE_TO_HIDE)

xmeLoggers.warn(messageOfWarning)
xmeLoggers.warnGroup( ...createMessageLinesToPrint('警告'))

xmeLoggers.error(messageOfError)
xmeLoggers.errorGroup(...createMessageLinesToPrint('报错'))

if (xmeLoggers.shouldLogLevel(3)) {
    console.log('该行【消息】根本不会打印。')
}



// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



const xmeLoggers = createXmeLoggers({
    messagePrefix: '功能块丙(这个功能块的名字很长,故本工具会在其名字后面自动折行)',

    /**
     * 注意,下方给出的值是一个我所谓【等级裁决函数】。
     * 不难理解,其含义是仅允许【等级】大于 3 的【消息】打印出来。
     */
    allowedLogMaxLevel_Or_LogLevelsTriage: l => l > 3,
})

xmeLoggers.log(0, MESSAGE_TO_HIDE)
xmeLoggers.log(1, MESSAGE_TO_HIDE)
xmeLoggers.log(2, MESSAGE_TO_HIDE)
xmeLoggers.log(3, MESSAGE_TO_HIDE)
xmeLoggers.log(4, createMessageToPrintOfLevel(4))
xmeLoggers.log(5, createMessageToPrintOfLevel(5))

/**
 * 【消息】是有【等级】的。
 * 下方第 1 个参数 4 即代表该组【多行消息】的【等级】为 4 。
 * 下方第 2 个参数 3 代表每行缩进 3 个空格。 */
console.log('注意:下面一组信息,将缩进明确配置为 3 个空格。')
xmeLoggers.logGroup(4, 3, ...createMessageLinesToPrint('日志'))

xmeLoggers.warn(messageOfWarning)

/**
 * 【警告】是没有所谓【等级】的。【警告】一律打印。
 * 故下方函数的调用不存在给出 2 个数字的参数形式。
 * 又,下方第 1 个参数不是数字。因此每行依照默认配置,缩进 4 个空格。 */
xmeLoggers.warnGroup(     ...createMessageLinesToPrint('警告'))

xmeLoggers.warn(messageOfError)

/**
 * 【报错】是没有所谓【等级】的。【报错】一律打印。
 * 故下方函数的调用不存在给出 2 个数字的参数形式。
 * 又,下方的数字 4 代表每行报错的行首缩进 4 个空格。 */
xmeLoggers.errorGroup(4,  ...createMessageLinesToPrint('报错'))

编程接口

根级别导出项

根级别导出项有 6 个,为:

  • 工厂函数 createXmeLoggers 。用以构建符合 T_XmeLogger_CreatedLoggers 接口的对象,即所谓【消息机集】。

    详见下文《TypeScript 诸接口详解 · 根导出项 createXmeLoggers》。

  • 常量 xmeLogLine_Short ,类型为 string ,值为连续 51 个 '-' 字符组成的字符串。

  • 常量 xmeLogLine_Long ,类型为 string ,值为连续 130 个 '-' 字符组成的字符串。

  • 常量 XmeLoggers_MessagePrefix_Default ,类型为 string ,值为 '未具名模块'

  • 常量 XmeLoggers_MessagePrefix_DecoAtStart ,类型为 string ,值为 '['

  • 常量 XmeLoggers_MessagePrefix_DecoAtEnd ,类型为 string ,值为 ']:'

TypeScript 接口总览
// 其中 `0` 代表对应的消息永不打印。
export type T_XmeLogLevel = 0 | 1 | 2 | 3 | 4 | 5;



/**
 * 此为一种函数。
 *
 * 此种函数用以裁决一条【消息】打印与否。
 *
 * 此种函数须返回一个 boolean 值。
 * 于给定的某条【消息】和给定的此种函数,
 * 若此种函数返回 `true` ,则该【消息】打印;
 * 若此种函数返回 `false` ,则该【消息】忽略。
 *
 * 又,此种函数由用户(即使用本软件的程序员们)自行设计并给出。
 */
export type T_XmeLogger_LogLevelTriageFunction = (logLevelOfSomeMessage: T_XmeLogLevel) => boolean;



export type T_XmeLogger_LogLevel_OrLogLevelTriage = T_XmeLogLevel | T_XmeLogger_LogLevelTriageFunction;



/** 表征单个【通用的消息机】,【消息等级】须临时由其第一个参数给出。 */
export type T_XmeLogger_LogFunction = (requiredLogLevel: T_XmeLogLevel, ...messageParts: Array<any>) => void;



/** 表征单个【已预设了消息等级的消息机】。 */
export type T_XmeLogger_LogFunction_OfSpecificLevel = (...messageParts: Array<any>) => void;



/**
 * 表征单个【带缩进功能的多行消息机】,适用于〖日志类〗的【多行消息】。
 * 又,可见该【消息机】有 3 种变体。
 */
export interface T_XmeLogger_LogFunction_MultipleLines {
    (requiredLogLevel: T_XmeLogLevel, /* | */ indentation: string | number, /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    (requiredLogLevel: T_XmeLogLevel, /* | */                               /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    (                                 /* | */                               /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
}



/** 下方类型表征〖警告类〗或〖报错类〗的单个【消息机】。 */
export type T_XmeLogger_WarningOrErrorReportingFunction = (...messageParts: Array<any>) => void;



/**
 * 表征单个【带缩进功能的多行消息机】,通用于〖警告类〗或〖报错类〗的【多行消息】。
 * 又,可见该【消息机】有 2 种变体。
 */
export interface T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines {
    (indentation: string | number, /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    (                              /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
}



/**
 * 下方接口类型表征【工厂函数】的产出(即【工厂函数】的返回值)。
 * 可见,每次调用【工厂函数】,会构建出一套 11 个【消息机】。它们大同小异。
 */
export interface T_XmeLogger_CreatedLoggers {
    log:             T_XmeLogger_LogFunction;
    logGroup:        T_XmeLogger_LogFunction_MultipleLines;

    logLevel1:       T_XmeLogger_LogFunction_OfSpecificLevel;
    logLevel2:       T_XmeLogger_LogFunction_OfSpecificLevel;
    logLevel3:       T_XmeLogger_LogFunction_OfSpecificLevel;
    logLevel4:       T_XmeLogger_LogFunction_OfSpecificLevel;
    logLevel5:       T_XmeLogger_LogFunction_OfSpecificLevel;

    shouldLogLevel:  T_XmeLogger_LogLevelTriageFunction;

    warn:            T_XmeLogger_WarningOrErrorReportingFunction;
    warnGroup:       T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines;

    error:           T_XmeLogger_WarningOrErrorReportingFunction;
    errorGroup:      T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines;
}
TypeScript 诸接口详解
  1. 主要的【根导出项】为工厂函数 createXmeLoggers
    export function createXmeLoggers (options?: {
        /** 该项不言自明。 */
        messagePrefix?:                         string;
    
        /**
         * 〖日志类〗【消息】均有【等级】。
         * 本参数的值用以裁定哪些【等级】的【消息】应打印,其余【消息】则忽略。
         * 本参数的值可以是一个函数。若确实给出了函数,则该函数不妨称【等级裁决函数】。
         * 该函数应返回一个 boolean 值。
         * 于某一条具体的【消息】,若该函数若返回值为 true ,则该【消息】被裁定为“应打印”;
         * 否则,该【消息】被裁定为“应忽略”。
         */
        allowedLogMaxLevel_Or_LogLevelsTriage?: T_XmeLogger_LogLevel_OrLogLevelTriage;
    
        /**
         * 当使用产出的【消息机】打印【多行消息】时,
         * 本参数设置【多行消息】中每行行首缩进空格数的默认值。
         */
        indentation?:                           string | number;
    }): T_XmeLogger_CreatedLoggers;

    这是一个工厂函数(暂称【甲】),用以构建一个对象(暂称【乙】)。

    【乙】携带一套所谓【消息机】(均暂称【丙】),以及 1 枚【等级裁决函数】(暂称【丁】)。

    目前,【丙】共有 11 枚,大同小异,分别针对不同的运用要求。如前所述,【丁】仅有 1 枚。

    【乙】的属性(亦即【丙】和【丁】)如下:

    1. 名为 log 的函数,暂称【丙1】。它符合 T_XmeLogger_LogFunction 接口。
    2. 名为 logLevel1 的函数,暂称【丙2】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    3. 名为 logLevel2 的函数,暂称【丙3】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    4. 名为 logLevel3 的函数,暂称【丙4】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    5. 名为 logLevel4 的函数,暂称【丙5】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    6. 名为 logLevel5 的函数,暂称【丙6】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    7. 名为 logGroup 的函数,暂称【丙7】。它符合 T_XmeLogger_LogFunction_MultipleLines 接口。
    8. 名为 warn 的函数,暂称【丙8】。它符合 T_XmeLogger_WarningOrErrorReportingFunction 接口。
    9. 名为 warnGroup 的函数,暂称【丙9】。它符合 T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines 接口。
    10. 名为 error 的函数,暂称【丙10】。它符合 T_XmeLogger_WarningOrErrorReportingFunction 接口。
    11. 名为 errorGroup 的函数,暂称【丙11】。它符合 T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines 接口。
    12. 名为 shouldLogLevel 的函数,暂称【丁】。它符合 T_XmeLogger_LogLevelTriageFunction 接口。

    简言之,【甲】构建出一系列【乙】(携带着【丙】和【丁】)。日常,开发者频繁使用【丙】和【丁】,而非【甲】。

    • 【工厂函数】的调用参数(唯壹壹个)

      工厂函数仅有一个调用参数,且可省略。其类型定义如下:

      options?: {
          messagePrefix?:                         string;
          allowedLogMaxLevel_Or_LogLevelsTriage?: T_XmeLogger_LogLevel_OrLogLevelTriage;
          indentation?:                           string | number;
      }

      其中:

      • options.messagePrefix?: string

        该值可省略。默认值为 '未具名模块'

        该组【消息机】每次打印任何消息时公用的所谓【前缀文字】。若该前缀文字过长,大于 16 个字符(即大于等于 17 个字符),则该前缀后面会自动换行。

      • options.allowedLogMaxLevel_Or_LogLevelsTriage?: T_XmeLogger_LogLevel_OrLogLevelTriage

        该值可省略。默认值为 2

        该值用以控制在控制台(Console)中打印消息的详尽程度。可取数字(T_XmeLogLevel)或一个函数(T_XmeLogger_LogLevelTriageFunction)。

        1. 若取函数,则该函数称所谓【等级裁决函数】。在每个〖日志类〗【消息机】的每次调用时,【等级裁决函数】该【消息机】收到的【消息】之【等级】,并决定是否打印该【消息】。具体而言,任何【消息】,凡【等级裁决函数】处理其【等级】后返回 true 者,该【消息】会被打印;反之,若【等级裁决函数】处理其【等级】后返回 false ,则该【消息】会被忽略。
        2. 若取数字,则须在 05 之间,含 0 ,含 5。若取 0 ,代表不打印任何消息;若取值 15 变化,则在控制的可能打印出的消息逐渐增多;反之。特别指出,若取 5 代表打印一切消息。
        3. 若取数字,但不在 05 之间,或取值根本是不数字,也不是函数,则本软件启用幕后预定的所谓“默认值”,即 2
      • options.indentation?: string | number

        专门用以控制【带缩进功能的多行消息机】在控制台(Console)中打印信息时,每行起始部位的缩进内容。一般的,人们喜欢用若干空格作为缩进内容,但亦不妨故意配置成任意文本。

        若该值取文本值(string),则原封不动沿用之;若该值取数字值,则代表每行首部应打印的连续空格的个数,以此形成所谓“缩进”。

        又,若该值取数字,则等效整数值(取 Math.ceil)不可小于 3 ,可以等于 3 。

        该值可省略。默认值为 4 ,即连续 4 个空格。

    • 【工厂函数】的返回值。

      下方接口类型表征【工厂函数】的产出(即【工厂函数】的返回值)。可见, 每次调用【工厂函数】,会构建出一套 11 个【消息机】 。它们大同小异。

      export interface T_XmeLogger_CreatedLoggers {
          log:             T_XmeLogger_LogFunction;
          logGroup:        T_XmeLogger_LogFunction_MultipleLines;
      
          logLevel1:       T_XmeLogger_LogFunction_OfSpecificLevel;
          logLevel2:       T_XmeLogger_LogFunction_OfSpecificLevel;
          logLevel3:       T_XmeLogger_LogFunction_OfSpecificLevel;
          logLevel4:       T_XmeLogger_LogFunction_OfSpecificLevel;
          logLevel5:       T_XmeLogger_LogFunction_OfSpecificLevel;
      
          shouldLogLevel:  T_XmeLogger_LogLevelTriageFunction;
      
          warn:            T_XmeLogger_WarningOrErrorReportingFunction;
          warnGroup:       T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines;
      
          error:           T_XmeLogger_WarningOrErrorReportingFunction;
          errorGroup:      T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines;
      }
  2. 工厂函数产出的、符合 T_XmeLogger_CreatedLoggers 接口的对象

    工厂函数产出一个对象,它是所谓【消息机集】。它包含 11 个属性(或者说字段)。这些属性的值全部都是函数。这些函数均称所谓【消息机】。这些【消息机】均可用以代替 console.logconsole.debugconsole.warnconsole.error 四者, 但不替代其余诸如 console.infoconsole.group 等。

  3. 工厂函数产出的对象中的 log 函数

    它是未预设【消息等级】的所谓【通用消息机】。恰因它未预设【消息等级】,调用它时,须在第 1 个参数给出【消息等级】。又,它用于取代 console.logconsole.debug 二者。

    log 函数的调用参数表(依次)

    • 第 1 参数 logLevelOfThisMessage: T_XmeLogLevel 。用以控制本次调用是否真执行 console.logconsole.debug 之一。

      若本参数 小于等于 工厂函数中收到的 allowedLogMaxLevel_Or_LogLevelsTriage ,则本次调用会执行 console.logconsole.debug ;否则,不会调用它们,故不会在控制台有所输出。

      又,若 logLevelOfThisMessage 小于 4 (不等于 4)时,采用 console.log ;否则,采用 console.debug

    • 除第 1 参数之外的一切参数,将原封不动的传递给 console.logconsole.debug

    返回值,无。

  4. 工厂函数产出的对象中的 logLevel1 ~ logLevel5 函数

    它们都是【已预设了消息等级的消息机】。

    它们之任一均可替代 console.logconsole.debug 二者。

    调用参数表(依次)

    • 一切参数均将原封不动的传递给 console.logconsole.debug

    返回值,无。

  5. 工厂函数产出的对象中的 logGroup 函数

    它是【多行消息机】。它用于取代 console.logconsole.debug 二者。

    该函数用以打印多行消息。每行消息的首部可以有相同的缩进。默认的缩进是连续 4 个空格。

    为了实现一次调用打印多行消息,且为了免去本工具的使用者(即是程序员们)反复添加或拼接换行符('\n'), 【多行消息机】要求一切【消息】均存放在列表(Array)中,每行【消息】一个列表,多行【消息】多个列表。 具体而言,【多行消息机】对给出的每个列表都调用一次 console.logconsole.debug ,多个列表则调用多次。 于某个列表,其一切成员将原封不动的传递给对应的 console.logconsole.debug

    又,为了控制消息的等级,也为了控制每行消息首部的缩进,【多行消息机】的消息机允许在参数表首部设计 1 个或 2 个特别的参数。这 1 个或 2 个参数必须出现在参数表的起始位置,即必须是第 1 和第 2 参数。它们之后的一切参数均代表逐行消息,故均须为列表(Array)。

    第 1 个参数,若不是列表(Array),则必须是数字,用以表征该组多行消息的【等级】。

    在第 1 个参数确是数字的前提下, 如果第 2 个参数不是列表(Array),则它必须是文字(string)或数字,用以表征该组多行消息逐行首部的缩进配置。又,若该值是文字值,则沿用;若该值是数字,且等效整数值(取 Math.ceil)大于等于 3 ,则代表逐行首部的缩进是有如数连续空格组成。若该值确是数字,但等效整数值小于等于 2 ,则本工具故意在控制台中给出警告,且逐行缩进配置采用默认值(应为连续 4 个空格)。

    还应注意到,不允许利用第 1 个参数表征逐行缩进配置。即不允许在给出【消息逐行缩进】配置时,却省略了【消息等级】指示。因为,若接口那般设计,须知【消息等级】和【消息逐行缩进】都是可以采用数字值的,于是使用者(应为程序员们)容易搞混、搞错。

    综上所述,【多行消息机】的接口描述略显复杂。实际使用反而显得较为简单。若以 Typescript 描述其接口,如下:

    function logGroup (logLevelOfTheseMessages: T_XmeLogLevel                                         , /* | */ indentation: string | number                                         , /* | */  ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    function logGroup (logLevelOfTheseMessages: T_XmeLogLevel                                         , /* | */                                                                        /* | */  ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    function logGroup (                                                                                 /* | */                                                                        /* | */  ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    function logGroup (               firstArg: T_XmeLogLevel | Array<any> | (() => Array<Array<any>>), /* | */   secondArg: string | number | Array<any> | (() => Array<Array<any>>), /* | */  ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void { /* 实现细节从略。 */ }

    调用参数表(依次)

    • 从略。参阅上文。

    返回值,无。

    示例若干:

    import {
        createXmeLoggers,
    } from '@xinmier/loggers'
    
    const xmeLoggers = createXmeLoggers('核心模块', 3)
    
    const value = true
    
    /**
     * 第 1 个参数是数字(本例为 5),代表本次打印的消息等级为该数字。
     */
    xmeLoggers.logWithIndetation(5,
        [ '第', 1, '行', '的', '内容', '。' ],
        [ '第 2 行的完整内容。' ],
        [ '第三行', 'value =', value, ',value 应该是【真】,假不了。' ]
    )
    
    /**
     * 第 1 个参数是数字(本例为 2),代表本次打印的消息等级为该数字。
     * 第 2 个参数是文本(本例为 '\t\t'),代表本次打印的消息(应有 3 行),每行首部均有 2 个 “制表符(tab)” 。
     */
    xmeLoggers.logWithIndetation(2, '\t\t',
        [ '第', 1, '行', '的', '内容', '。' ],
        [ '第 2 行的完整内容。' ],
        [ '第三行', 'value =', value, ',value 应该是【真】,假不了。' ]
    )
    
    /**
     * 省略了表征【消息等级】的数字,
     * 也省略了表征【消息逐行缩进】的文字配置,
     *
     * 故,
     *     -   本例的消息等级取默认值 3 。
     *     -   本例的逐行首部缩进取默认值 4 ,即连续 4 个空格。
     */
    xmeLoggers.logWithIndetation(
        [ '第', 1, '行', '的', '内容', '。' ],
        [ '第 2 行的完整内容。' ],
        [ '第三行', 'value =', value, ',value 应该是【真】,假不了。' ]
    )
  6. 工厂函数产出的对象中的 warn 函数

    它是所谓〖警告类〗的【通用消息机】。它用于取代 console.warn

    warn 函数的调用参数表(依次)

    -   一切参数均将原封不动的传递给 `console.warn` 。

    返回值,无。

  7. 工厂函数产出的对象中的 warnGroup 函数

    它是所谓〖警告类〗的【多行消息机】。它用于取代 console.warn

    为了实现一次调用打印多行消息,且为了免去本工具的使用者(即是程序员们)反复添加或拼接换行符('\n'), 【多行消息机】要求一切【消息】均存放在列表(Array)中,每行【消息】一个列表,多行【消息】多个列表。 具体而言,【多行消息机】对给出的每个列表都调用一次 console.warn ,多个列表则调用多次。 于某个列表,其一切成员将原封不动的传递给对应的 console.warn

    若以 Typescript 描述其接口,如下:

    function warnGroup (indentation: string | number                                         , /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    function warnGroup (                                                                       /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    function warnGroup (   firstArg: string | number | Array<any> | (() => Array<Array<any>>), /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void { /* 实现细节从略。 /* }

    warnGroup 函数的调用参数表(依次)

    • 从略。参阅上文。

    返回值,无。

  8. 工厂函数产出的对象中的 error 函数

    它是所谓〖报错类〗的【通用消息机】。它用于取代 console.error

    error 函数的调用参数表(依次)

    -   一切参数均将原封不动的传递给 `console.error` 。

    返回值,无。

  9. 工厂函数产出的对象中的 errorGroup 函数

    它是所谓〖报错类〗的【多行消息机】。它用于取代 console.error

    为了实现一次调用打印多行消息,且为了免去本工具的使用者(即是程序员们)反复添加或拼接换行符('\n'), 【多行消息机】要求一切【消息】均存放在列表(Array)中,每行【消息】一个列表,多行【消息】多个列表。 具体而言,【多行消息机】对给出的每个列表都调用一次 console.error ,多个列表则调用多次。 于某个列表,其一切成员将原封不动的传递给对应的 console.error

    function errorGroup (indentation: string | number                                         , /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    function errorGroup (                                                                       /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
    function errorGroup (   firstArg: string | number | Array<any> | (() => Array<Array<any>>), /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void { /* 实现细节从略。 */ }

    errorGroup 函数的调用参数表(依次)

    • 从略。参阅上文。

    返回值,无。

  10. 工厂函数产出的对象中的 shouldLogLevel 函数

    它是所谓〖日志类〗【消息】的【等级裁决函数】。形制如下:

    type T_XmeLogger_LogLevelTriageFunction = (logLevelOfSomeMessage: T_XmeLogLevel) => boolean;

    shouldLogLevel 函数的调用参数表(依次)

    1. logLevelToCheck: T_XmeLogLevel

    返回值,boolean

用法(面向本工具的设计者和维护者)

暂无。