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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@docs-islands/logger

v0.0.3

Published

Shared runtime logger and compile-time pruning plugin for docs-islands packages

Downloads

390

Readme

@docs-islands/logger

English | 简体中文

面向 docs-islands 包和用户工具的框架无关 logger:提供统一的 Node.js / 浏览器运行时日志 API、可预测的可见性策略,以及可选的构建期插件,用来从生产产物中移除静态可判定为隐藏的日志调用。

特性

  • 精简公共 API:从 @docs-islands/logger 导入 createLoggersetLoggerConfigresetLoggerConfig 即可。
  • 同时支持 Node.js 与浏览器:终端环境尽量使用彩色输出,浏览器环境使用 styled console 输出。
  • 分组日志流:用 package main 和小写点分命名空间 group 组织日志,例如 build.pipeline
  • 可配置可见性:全局或按规则控制 errorwarninfosuccess
  • Debug 诊断:简单配置下可开启 debug 输出;规则模式下会给可见日志附加命中规则 label 与 elapsed timing 信息。
  • 生产环境裁剪loggerPlugin 会移除被配置隐藏、且能静态证明安全的日志调用。
  • Scoped 集成 API:宿主包可以创建显式 logger scope,而不必修改 root runtime 策略。
  • 基于 unplugin 的构建工具覆盖:支持 Vite、Rollup、Rolldown、esbuild、webpack、Rspack 与 Farm。
  • TypeScript 优先:通过 package exports 提供 ESM 与 TypeScript 类型。

安装

pnpm add @docs-islands/logger
npm install @docs-islands/logger
yarn add @docs-islands/logger
bun add @docs-islands/logger

环境要求:

  • Node.js ^20.19.0 || >=22.12.0
  • 支持 ESM 的运行时或构建工具
  • 根据使用的构建插件安装对应的可选 peer dependency,例如 Rollup 需要 @rollup/plugin-replace,Rolldown 需要 rolldown

快速开始

import { createLogger, setLoggerConfig } from '@docs-islands/logger';

setLoggerConfig({
  debug: true,
  levels: ['info', 'warn', 'error'],
});

const logger = createLogger({
  main: '@acme/docs',
}).getLoggerByGroup('build.pipeline');

logger.info('build started', { elapsedTimeMs: 12.34 });
logger.success('build finished', { elapsedTimeMs: 42.8 });
logger.warn('cache is cold');
logger.error('build failed');
logger.debug('debug details');

createLogger({ main }) 用来标识日志流所属的包或子系统。getLoggerByGroup(group) 用来标识更细的功能区域。group 必须使用小写点分命名空间,且不能带 package 标识,例如 runtime.reactbuild.pipeline

如果没有使用 loggerPlugin,也没有在创建 logger 前调用 setLoggerConfig(...),运行时会回退到默认可见性策略。

配置归属

@docs-islands/logger 的 root 入口背后有一个默认 scope,同时也为宿主集成提供显式 scope。创建 logger 前应先确认配置归属:

| 场景 | 入口 | 配置归属 | | ---------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | 直接应用、脚本或独立工具 | @docs-islands/logger | 应用侧通过 setLoggerConfig(...)resetLoggerConfig() 管理默认 scope。 | | 构建工具接管的 runtime | @docs-islands/logger@docs-islands/logger/plugin | 构建插件注入默认 scope 配置。应用代码调用 setLoggerConfig(...)resetLoggerConfig() 会抛错。 | | 需要私有归属的宿主或框架集成 | @docs-islands/logger/core | 宿主创建显式 scope,并在 createScopedLogger(...) 前调用 setScopedLoggerConfig(scopeId, config)。 |

可复用 library 不应该在模块初始化时调用 setLoggerConfig(...)resetLoggerConfig()。默认 scope 属于拥有 runtime 的应用或 bundler host。

Runtime 配置

默认可见级别是 errorwarninfosuccessdebug 日志默认隐藏;只有在没有配置规则的简单模式下设置 debug: truedebug 日志才会显示。

setLoggerConfig({
  levels: ['warn', 'error'],
});

直接、非插件接管的场景下,使用 resetLoggerConfig() 清空默认 runtime 配置:

resetLoggerConfig();

当 runtime 由 loggerPlugin 接管时,setLoggerConfig(...)resetLoggerConfig() 都会抛错。请改为更新插件的 config

规则模式

规则会把日志策略切换成 allowlist。只要存在至少一个 active rule,日志就必须命中某条规则,并且该规则允许当前级别,才会输出。未命中的日志不会回退到 root levels

setLoggerConfig({
  debug: true,
  levels: ['warn', 'error'],
  rules: [
    {
      label: 'metrics',
      main: '@acme/docs',
      group: 'userland.metrics',
      levels: ['info', 'warn'],
    },
    {
      enabled: false,
      label: 'noisy-devtools',
      group: 'devtools.*',
    },
  ],
});

规则字段:

| 字段 | 说明 | | --------- | ------------------------------------------------------------ | | label | 必填且必须唯一。debug 模式下,可见的规则日志会显示该 label。 | | enabled | 设置为 false 后,规则保留但不参与匹配。 | | main | 精确匹配 package 或子系统。 | | group | 默认精确匹配;包含 glob 字符时按 glob pattern 匹配。 | | message | 默认精确匹配;包含 glob 字符时按 glob pattern 匹配。 | | levels | 当前规则允许的非 debug 级别。 |

levels 只接受 errorwarninfosuccessdebugdebug: true 控制,不放进 levels

构建插件

当你需要由构建工具注入 runtime config,并在生产构建中做日志裁剪时,使用 @docs-islands/logger/plugin

import { defineConfig } from 'vite';
import { loggerPlugin } from '@docs-islands/logger/plugin';

export default defineConfig({
  plugins: [
    loggerPlugin.vite({
      config: {
        levels: ['warn', 'error'],
      },
    }),
  ],
});

插件提供 unplugin adapter:

loggerPlugin.vite(options);
loggerPlugin.rollup(options);
loggerPlugin.rolldown(options);
loggerPlugin.esbuild(options);
loggerPlugin.webpack(options);
loggerPlugin.rspack(options);
loggerPlugin.farm(options);

插件选项:

| 选项 | 说明 | | ----------- | ----------------------------------------------------------------------- | | config | 注入 bundle 的 runtime LoggerConfig。省略时使用默认可见性策略。 | | treeshake | 默认为 true。设置为 false 后保留所有日志调用,只依赖 runtime 过滤。 |

Rollup 宿主 bundler 在使用 loggerPlugin.rollup(...) 前,需要主动安装 @rollup/plugin-replace。logger plugin 会把 Rollup 的 replace plugin 插到插件链前面,用它内联 logger 控制常量,包括 __DOCS_ISLANDS_DEFAULT_LOGGER_CONTROLLED____DOCS_ISLANDS_DEFAULT_LOGGER_CONFIG__,让 Rollup bundle 拿到与其他 bundler 通过 define hook 注入时相同的序列化 runtime config。

当 runtime 由 loggerPlugin 接管时,应用代码里调用 setLoggerConfig(...)resetLoggerConfig() 会抛错。请改为更新插件的 config,这样构建期裁剪与 runtime 过滤会共享同一套策略。

Tree-Shaking 范围

Tree-shaking 会保持保守。runtime 策略永远是最终依据;插件只会移除能够证明安全的调用。

只有插件能静态看到以下信息时,日志调用才可能被移除:

  • createLogger 必须是从 @docs-islands/logger 命名导入,且没有起别名
  • maingroup 和 message 都是字符串字面量
  • logger binding 没有被重新赋值
  • 日志调用是独立表达式
  • 插件运行在 build 上下文中,且 treeshake 没有设置为 false

支持裁剪的静态写法:

import { createLogger } from '@docs-islands/logger';

const logger = createLogger({
  main: '@acme/docs',
}).getLoggerByGroup('userland.metrics');

logger.info('static metric ready');
logger.warn('static metric delayed');
logger.error('static metric failed');
logger.success('static metric uploaded');
logger.debug('static metric details');

以下写法会保留,并交给 runtime 过滤:

  • 动态的 maingroup 或 message
  • createLogger 起别名的 import
  • 被重新赋值的 logger binding
  • 解构出的日志方法
  • computed method access
  • 非独立表达式,例如把日志调用结果赋值给变量

API

Root 入口:

import { createLogger, resetLoggerConfig, setLoggerConfig } from '@docs-islands/logger';

| API | 说明 | | --------------------- | ------------------------------------------------------------------------------------- | | createLogger() | 在默认 scope 中创建或复用 main logger。继续调用 .getLoggerByGroup(group) 后写日志。 | | setLoggerConfig() | 为直接、非插件用法设置默认 runtime config。插件接管 runtime 中会抛错。 | | resetLoggerConfig() | 为直接、非插件用法清空默认 runtime config。插件接管 runtime 中会抛错。 |

插件入口:

import { loggerPlugin } from '@docs-islands/logger/plugin';

Scoped 集成入口:

import {
  createScopedLogger,
  getScopedLoggerConfig,
  resetScopedLoggerConfig,
  setScopedLoggerConfig,
  shouldSuppressLog,
} from '@docs-islands/logger/core';
import { createLoggerScopeId } from '@docs-islands/logger/core/helper';

const scopeId = createLoggerScopeId();

setScopedLoggerConfig(scopeId, {
  levels: ['warn', 'error'],
});

const scopedLogger = createScopedLogger({ main: '@acme/docs-host' }, scopeId);
const logger = scopedLogger.getLoggerByGroup('build.pipeline');

logger.warn('host warning');

resetScopedLoggerConfig(scopeId);

| API | 说明 | | --------------------------- | ------------------------------------------------------------------- | | setScopedLoggerConfig() | 注册或更新显式 logger scope。必须在 createScopedLogger() 前调用。 | | createScopedLogger() | 在显式 scope 内创建或复用 main logger。 | | getScopedLoggerConfig() | 读取某个 scope 的当前配置;未注册时返回 undefined。 | | resetScopedLoggerConfig() | 移除显式 scope 配置。 | | shouldSuppressLog() | 为自定义集成逻辑解析 runtime 可见性。 |

高级类型与 helper 入口:

import type { LoggerConfig } from '@docs-islands/logger/types';
import { createElapsedLogOptions } from '@docs-islands/logger/helper';
import { createLoggerScopeId, normalizeLoggerConfig } from '@docs-islands/logger/core/helper';

应用代码优先使用 root 入口。只有集成侧需要显式 scope 时才使用 @docs-islands/logger/core。共享的格式化、elapsed-time、error/debug-message 工具从 @docs-islands/logger/helper 导入;scope 与 config normalize 工具从 @docs-islands/logger/core/helper 导入。

文档

贡献

欢迎贡献。从仓库根目录运行:

pnpm --filter @docs-islands/logger test
pnpm --filter @docs-islands/logger typecheck
pnpm --filter @docs-islands/logger lint:package

提交 PR 前,请阅读 贡献指南

许可证

MIT © XiSenao