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

@w57124/exs-monitor-sdk

v0.1.15

Published

前端监控 SDK:错误上报、性能指标、网络拦截

Downloads

42

Readme

EXS Monitor SDK

前端监控 SDK:错误上报、性能指标、网络拦截。打包为 ESM/CJS/IIFE,支持浏览器直接注入与构建工具使用。

安装

npm i @w57124/exs-monitor-sdk

使用

import { MonitorClient } from '@w57124/exs-monitor-sdk'

const client = new MonitorClient({
  dsn: 'https://your-collector.example.com/ingest',
  appVersion: '1.0.0',
  enableErrors: true,
  enablePerformance: true,
  enableNetwork: true,
  transport: { 
    batch: true, 
    batchSize: 20, 
    flushIntervalMs: 5000,
    uploadMethod: 'auto' // 'beacon' | 'fetch' | 'auto',默认 'auto'
  },
  // 新增:捕获回调,可同步拿到完整事件(含 logID)
  onEventCaptured: (event) => {
    console.log('captured event logID:', event.logID, 'type:', event.type)
    // 可以把 event.logID 回传给页面或日志系统
  }
})

// 手动上报时,capture 会返回完整事件(含 logID)
const event = client.capture('custom', { action: 'page_view' })
console.log('manual capture event', event.logID, event)

白屏检测(可选)

const client = initMonitor({
  dsn: 'https://your-collector.example.com/ingest',
  enableWhiteScreen: true,
  whiteScreenOptions: {
    delayMs: 3000,           // 首次检测延迟
    minVisibleCount: 2,      // 视口内可见元素阈值(<= 判定白屏)
    minArea: 2500,           // 单元素最小面积阈值(px^2)
    sampleTimes: 3,          // 采样次数(连续采样)
    sampleIntervalMs: 1000,  // 采样间隔
    includePerf: true        // 是否附带性能快照(TTFB/DCL/Load/FCP/LCP)
  }
})

说明:将 `includePerf` 设为 `false` 可关闭性能快照以节省带宽。

本地存储模式与事件查看器

import { initMonitor } from '@w57124/exs-monitor-sdk'

const client = initMonitor({
  dsn: '', // 本地模式可为空
  transport: { mode: 'local', localKey: '__EXSMONITOR_EVENTS__', localMaxItems: 500 },
  enableErrors: true,
  enablePerformance: true,
  enableNetwork: true
})

// 打开事件列表 UI(覆盖层)
client.openEventList()

// 如需自定义渲染,也可:
// import { openEventViewer } from '@w57124/exs-monitor-sdk'
// openEventViewer(client.getStoredEvents(), () => client.clearStoredEvents())

快捷键(手动绑定/解绑):不再默认启用,请按需绑定。

import { bindViewerHotkeyDefault, unbindViewerHotkeyDefault } from '@w57124/exs-monitor-sdk'

// 绑定快捷键(默认 'Ctrl+Shift+M',可传入 'Alt+K' 等自定义)
bindViewerHotkeyDefault('Alt+K')

// 解绑
unbindViewerHotkeyDefault()

网络拦截域名与 URL 过滤

initMonitor({
  enableNetwork: true,
  networkHostsAllowlist: ['api.example.com', '*.internal.example.com'],
  networkHostsBlocklist: ['blocked.example.com'],
  networkUrlAllowPatterns: [/\/v1\/orders\//, '^https://api.example.com/v2/'],
  networkUrlBlockPatterns: ['\\.png$', '\\.(css|js)$'],
  networkMaxBodyLength: 1000  // 请求/响应 body 最大长度(默认 1000),超出截断并标记,设为 0 表示不上报 body
})

说明:

  • 网络事件上报包含 requestBodyresponseBody(仅在存在时)
  • networkMaxBodyLength 控制最大字符数,超出部分会被截断并添加 ...[truncated] 标记
  • 设为 0 或负数可完全禁用 body 上报以节省带宽

事件 ID 与上传格式

  • 事件 ID 字段:事件对象使用 logID 字段作为唯一标识(不再是 id
  • 批量上传模式transport.batch: true,默认):
    • 达到批量大小或定时触发时,批量发送整个队列
    • 上传格式:{ events: [...] }(数组包装)
  • 非批量上传模式transport.batch: false):
    • 每次只取队列第一个事件发送
    • 上传格式:单个事件对象(不是数组包装)

上传方式选择

通过 transport.uploadMethod 参数可以选择上传方式:

initMonitor({
  dsn: 'https://your-collector.example.com/ingest',
  transport: {
    uploadMethod: 'beacon', // 可选值:'beacon' | 'fetch' | 'auto'
    batch: true
  }
})
  • 'beacon':仅使用 sendBeacon 方式上传
    • 优点:页面卸载时更可靠,不会阻塞页面关闭
    • 限制:不支持自定义请求头(headers),数据以 Blob(application/json) 发送
    • 适用场景:不需要自定义 headers 的场景,或页面卸载时需要可靠上报
  • 'fetch':仅使用 fetch 方式上传
    • 优点:支持自定义请求头(headers),更灵活
    • 限制:页面卸载时可能不可靠
    • 适用场景:需要自定义 headers(如认证令牌)的场景
  • 'auto':自动选择(默认)
    • 优先使用 sendBeacon,失败则自动回退到 fetch
    • 兼顾可靠性和灵活性

死循环防护

SDK 内置了死循环防护机制,防止上报接口的错误被错误捕获和网络拦截再次上报:

  • 网络拦截防护:SDK 的上报请求会自动添加 X-EXS-Monitor-SDK header 标记,网络拦截会自动跳过这些请求
  • 错误捕获防护:错误捕获机制会自动过滤上报接口相关的错误,避免形成死循环
  • URL 匹配防护:通过 URL 匹配识别 SDK 自己的上报请求,确保不会被拦截

这些防护机制是自动启用的,无需额外配置。

浏览器直接使用(IIFE,全局变量 EXSMonitorSDK

<script src="/dist/index.global.js"></script>
<script>
  // 方式一:直接调用导出函数
  const client = EXSMonitorSDK.initMonitor({ dsn: 'https://...' })
  client.capture('custom', { hello: 'world' })

  // 方式二:在 script 之前放置全局配置,可自动初始化
  // <script>window.__EXSMONITOR__ = { dsn: 'https://...' }</script>
  // <script src="/dist/index.global.js"></script>
</script>

发布

  • 更新 package.jsonnameversionrepository
  • npm run build
  • npm publish --access public

许可

MIT

文档(TypeDoc)

生成 API 文档到 docs/

npm run docs

附录:sendBeacon 行为与兼容性

  • 上传方式控制:通过 transport.uploadMethod 参数可以选择上传方式('beacon' | 'fetch' | 'auto'
  • 自动模式:当 uploadMethod: 'auto'(默认)且 transport.useBeacon 开启时,SDK 优先使用 sendBeacon,失败则自动回退到 fetch
  • Header 限制sendBeacon 不能自定义请求头,SDK 会以 Blob(application/json) 发送;若服务端依赖认证头,请使用 uploadMethod: 'fetch' 或改为从 URL 查询参数或请求体字段携带令牌
  • 方法与时机sendBeacon 仅支持 POST,设计为在页面卸载时仍能可靠发送;SDK 在 visibilitychange(hidden)pagehidebeforeunload 时尝试最后一次 flush
  • 体积与序列化:请保持单次批量 payload 尽量小(建议 < 64KB),超大 payload 可能被浏览器丢弃;SDK 默认批量大小可通过 transport.batchSize 控制
  • 兼容性useBeacon 参数已保留用于向后兼容,但推荐使用 uploadMethod 参数进行更精确的控制