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

aemeath-js

v1.7.0

Published

A modular, type-safe logging system with plugin architecture

Readme


v2.0 Beta 已发布 — 新增多平台支持(浏览器 + 微信 / 支付宝 / 抖音 / 百度小程序 + Taro / uni-app)。安装:npm install aemeath-js@beta查看更新内容 →


它做什么

错误追踪、日志管理、性能监控 —— 全部在浏览器端完成。后端只需接收和存储数据。

  • 🌲 Tree-shakable — 按需引入,未使用的代码不会被打包
  • 🔓 前端驱动 — 队列调度、重试、缓存、去重全部在客户端运行
  • 🌐 框架支持 — React、Vue、原生 JS、jQuery
  • 🔧 构建工具支持 — Vite、Webpack 4+、Rsbuild

安装

npm install aemeath-js
yarn add aemeath-js
# 或
pnpm add aemeath-js

快速开始

// 初始化一次(如在 main.ts 中)
import { initAemeath } from 'aemeath-js';

initAemeath({
  upload: async (log) => {
    const res = await fetch('/api/logs', {
      method: 'POST',
      body: JSON.stringify(log),
    });
    const data = await res.json();
    return data.code === 200
      ? { success: true }
      : { success: false, shouldRetry: true, error: data.message };
  },
  context: {
    userId: '12345',
    appVersion: '1.0.0',
  },
});
// 任何地方使用
import { getAemeath } from 'aemeath-js';

const logger = getAemeath();
logger.info('用户已登录');
logger.error('出错了', { error });
logger.updateContext('userId', '67890');

默认已启用哪些插件? initAemeath() 会自动启用以下插件,无需额外 .use()

| 插件 | 默认状态 | 如何关闭 | |------|---------|---------| | ErrorCapturePlugin | ✅ 默认启用 | errorCapture: false | | SafeGuardPlugin | ✅ 默认启用 | safeGuard: { enabled: false } | | NetworkPlugin | ✅ 默认启用 | network: { enabled: false } | | UploadPlugin | 传入 upload 时启用 | 不传 upload 即可 | | EarlyErrorCapturePlugin | 配置了构建插件时自动启用 | — |

💡 需要更多能力? 你可以随时通过 .use() 追加插件。重复调用 .use() 是安全的——已安装的插件不会被重复添加。

浏览器直接使用(无需构建工具)

适用于 jQuery、原生 JS、静态 HTML 页面 — 无需 npm:

<script src="https://unpkg.com/aemeath-js/dist/aemeath-js.global.js"></script>
<script>
  AemeathJs.init({
    upload: function(log) {
      fetch('/api/logs', { method: 'POST', body: JSON.stringify(log) });
    }
  });

  var logger = AemeathJs.getAemeath();
  logger.info('页面加载完成');
</script>

插件

所有插件均为可选。只导入你需要的 — 未使用的插件会被 tree-shaking 移除。

| 插件 | 说明 | 体积 | |------|------|------| | ErrorCapturePlugin | 自动捕获全局错误、未处理的 Promise 拒绝、资源加载失败 | ~3KB | | EarlyErrorCapturePlugin | 捕获 React/Vue 挂载前的错误(需配合构建插件) | ~3KB | | UploadPlugin | 带优先级队列、重试和本地缓存的日志上报 | ~5KB | | PerformancePlugin | 🧪 Web Vitals 性能监控(了解更多) | ~4KB | | NetworkPlugin | 监控 fetch/XHR 请求(错误、慢请求) | ~3KB | | SafeGuardPlugin | 频率限制、递归保护、错误预算 | ~3KB | | BeforeSendPlugin | 🛡️ 全链路最终拦截,用于隐私脱敏 / 过滤(文档) | <1KB |

想精确控制插件执行顺序?请看 插件执行顺序(priority 字段)。

beforeSend — 隐私保护与脱敏

import { initAemeath } from 'aemeath-js';

initAemeath({
  upload: async (log) => { /* ... */ },
  // 修改、丢弃或放行任意一条日志(包括 NetworkPlugin 自动捕获的网络日志)
  beforeSend: (entry) => {
    // NetworkPlugin 把网络日志标记为 errorCategory: 'http',
    // 并把 url / requestData / responseData 写在 entry.context 上(详见 docs/zh/9-before-send.md)
    if (entry.tags?.errorCategory === 'http' && entry.context) {
      return {
        ...entry,
        context: {
          ...entry.context,
          requestData: '[REDACTED]',
          responseData: '[REDACTED]',
        },
      };
    }
    return entry;
  },
});

返回 null 可完全丢弃该条日志。完整 API 见 docs/zh/9-before-send.md

框架集成

⚠️ 重要: 无论使用哪个框架,都需要先在应用入口(如 main.ts)调用 initAemeath() 进行初始化。下面的框架集成不是替代初始化,而是在组件中便捷地获取同一个单例实例。

| 框架 | 导入路径 | 主要导出 | |------|----------|----------| | React 16.8+ | aemeath-js/react | AemeathErrorBoundary, useAemeath(), useErrorCapture(), withErrorBoundary() | | Vue 3+ | aemeath-js/vue | createAemeathPlugin(), useAemeath(), useErrorCapture() | | 原生 JS / jQuery | aemeath-js | 核心 API(无需额外导入) |

// main.tsx — 第一步:初始化(和快速开始一样)
import { initAemeath } from 'aemeath-js';

initAemeath({
  upload: async (log) => { /* ... */ return { success: true }; },
});
// App.tsx — 第二步:使用框架集成
import { AemeathErrorBoundary, useAemeath } from 'aemeath-js/react';

function App() {
  return (
    <AemeathErrorBoundary
      fallback={(error, reset) => (
        <div>
          <p>出错了:{error.message}</p>
          <button onClick={reset}>重试</button>
        </div>
      )}
    >
      <MyApp />
    </AemeathErrorBoundary>
  );
}

// useAemeath() 返回的就是 initAemeath() 创建的同一个实例
function MyComponent() {
  const logger = useAemeath();
  logger.info('组件已挂载');
  return <div>...</div>;
}
// main.ts — 第一步:初始化(和快速开始一样)
import { createApp } from 'vue';
import { initAemeath } from 'aemeath-js';
import { createAemeathPlugin } from 'aemeath-js/vue';

initAemeath({
  upload: async (log) => { /* ... */ return { success: true }; },
});

const app = createApp(App);
app.use(createAemeathPlugin({ captureWarnings: true }));
app.mount('#app');
<!-- MyComponent.vue — 第二步:useAemeath() 返回的是同一个单例 -->
<script setup>
import { inject } from 'vue';
import { useAemeath } from 'aemeath-js/vue';

const logger = useAemeath(inject);
logger.info('组件初始化');
</script>

构建工具插件

| 构建工具 | 早期错误捕获 | SourceMap 上传 | |----------|-------------|---------------| | Vite 2+ | aemeath-js/build-plugins/vite | aemeath-js/build-plugins/vite-sourcemap | | Webpack 4+ | aemeath-js/build-plugins/webpack | aemeath-js/build-plugins/webpack-sourcemap | | Rsbuild 1+ | aemeath-js/build-plugins/rsbuild | aemeath-js/build-plugins/rsbuild-sourcemap |

// vite.config.ts
import { ameathEarlyErrorPlugin } from 'aemeath-js/build-plugins/vite';
import { ameathViteSourceMapPlugin } from 'aemeath-js/build-plugins/vite-sourcemap';

export default defineConfig({
  build: { sourcemap: true },
  plugins: [
    ameathEarlyErrorPlugin({ enabled: true }),
    ameathViteSourceMapPlugin({
      onUpload: async (file) => {
        await fetch('/api/sourcemaps', { method: 'POST', body: file.content });
      },
      deleteAfterUpload: true,
    }),
  ],
});
// webpack.config.js
const { AemeathEarlyErrorWebpackPlugin } = require('aemeath-js/build-plugins/webpack');
const { AemeathSourceMapWebpackPlugin } = require('aemeath-js/build-plugins/webpack-sourcemap');

module.exports = {
  devtool: 'source-map',
  plugins: [
    new AemeathEarlyErrorWebpackPlugin({ enabled: true }),
    new AemeathSourceMapWebpackPlugin({
      onUpload: async (file) => {
        await fetch('/api/sourcemaps', { method: 'POST', body: file.content });
      },
    }),
  ],
};
// rsbuild.config.ts
import { ameathEarlyErrorPlugin } from 'aemeath-js/build-plugins/rsbuild';
import { ameathSourceMapPlugin } from 'aemeath-js/build-plugins/rsbuild-sourcemap';

export default defineConfig({
  output: { sourceMap: { js: 'source-map' } },
  plugins: [
    ameathEarlyErrorPlugin({ enabled: true }),
    ameathSourceMapPlugin({
      onUpload: async (file) => {
        await fetch('/api/sourcemaps', { method: 'POST', body: file.content });
      },
    }),
  ],
});

打包体积

| 配置 | 体积 | 包含内容 | |------|------|----------| | 仅核心 | ~2KB | Logger + 事件系统 | | + 错误捕获 | ~5KB | + 全局错误处理 | | + 上报 | ~10KB | + 队列、重试、缓存 | | 全部插件 | ~15KB | 所有功能 |

自定义插件

import type { AemeathPlugin, AemeathInterface } from 'aemeath-js';

class MyPlugin implements AemeathPlugin {
  readonly name = 'my-plugin';
  readonly version = '1.0.0';

  install(logger: AemeathInterface) {
    logger.on('log', (entry) => {
      // 你的自定义逻辑
    });
  }

  uninstall(logger: AemeathInterface) {
    // 清理
  }
}

logger.use(new MyPlugin());

文档

| 文档 | 说明 | |------|------| | 快速开始 | 分步骤的安装使用指南 | | 错误捕获 | 全局错误捕获插件 | | 早期错误捕获 | 挂载前错误捕获 + 构建插件 | | SourceMap 解析 | 解析混淆的错误堆栈 | | 上报插件 | 带队列和重试的日志上报 | | 全局上下文 | 自动附加上下文到每条日志 | | 性能监控 | 🧪 Web Vitals 性能监控(实验性) | | 插件执行顺序 | 🧩 通过 priority 控制插件执行顺序 | | beforeSend 钩子 | 🛡️ 全链路最终拦截,用于隐私脱敏 / 过滤 | | 浏览器直接使用 | Script 标签引入(无需构建工具) |

📖 English docs: README | Quick Start | Module Docs

兼容性

浏览器

所有产物(ESM、CJS、IIFE)均以 ES2017 为构建目标,可直接在以下浏览器中运行:

| 环境 | 最低版本 | 说明 | |------|---------|------| | Chrome | 64+ | 完整支持 | | Firefox | 69+ | 完整支持 | | Safari | 12+ | 完整支持 | | Edge | 79+(Chromium) | 完整支持 | | iOS Safari | 12+ | 完整支持 | | Android WebView | 64+ | 完整支持 | | IE | ❌ 不支持 | 如需兼容可使用浏览器 IIFE 包 + polyfill |

兼容更低版本浏览器(Chrome < 64)

如果你的 browserslist 包含上述表格之前的浏览器版本,需要将 aemeath-js 加入构建工具的转译范围:

Rsbuild / Rspack

// rsbuild.config.ts
export default defineConfig({
  source: {
    include: [/[\\/]node_modules[\\/]aemeath-js[\\/]/],
  },
});

Webpack

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.m?js$/,
        include: [
          path.resolve(__dirname, 'src'),
          /node_modules[\\/]aemeath-js/,
        ],
        use: {
          loader: 'babel-loader',
          options: {
            presets: [['@babel/preset-env', { targets: '> 0.5%, not dead' }]],
          },
        },
      },
    ],
  },
};

Vite

Vite 使用 esbuild 构建,默认跳过 node_modules。对于需要兼容低版本浏览器的生产构建,请使用 @vitejs/plugin-legacy

// vite.config.ts
import legacy from '@vitejs/plugin-legacy';

export default defineConfig({
  plugins: [
    legacy({
      targets: ['Chrome >= 49'],
    }),
  ],
});

Next.js

// next.config.js
module.exports = {
  transpilePackages: ['aemeath-js'],
};

Node.js

| 用途 | 最低版本 | 说明 | |------|---------|------| | 构建插件(Vite/Webpack/Rsbuild) | Node 16+ | 在构建工具进程中运行 | | SourceMap 解析器 | Node 16+ | 服务端堆栈解析 | | 核心 / 插件 | 仅浏览器 | 依赖 windowdocument |

构建工具

| 工具 | 支持版本 | 集成方式 | |------|---------|----------| | Vite | 2.0+ | 一等公民插件支持 | | Webpack | 4.0+ | Plugin + Loader | | Rsbuild | 1.0+ | 一等公民插件支持 | | Rollup | 2.0+ | 通过 Vite 插件 | | esbuild | 0.14+ | 兼容 ESM/CJS 输出 | | tsup | 6.0+ | 开箱即用 |

框架

| 框架 | 支持版本 | 集成方式 | |------|---------|----------| | React | 16.8+(Hooks) | aemeath-js/react — ErrorBoundary、Hooks | | Vue | 3.0+ | aemeath-js/vue — Plugin、Composables | | Next.js | 12+ | 通过 React 集成 | | Nuxt | 3+ | 通过 Vue 集成 | | 原生 JS / jQuery | 任意 | 核心 API,无需额外导入 |

模块格式

| 格式 | 文件 | 构建目标 | 用途 | |------|------|----------|------| | ESM | dist/index.js | ES2017 | import — 现代打包工具 | | CJS | dist/index.cjs | ES2017 | require() — Node.js、旧版打包工具 | | IIFE | dist/aemeath-js.global.js | ES2017 | <script> 标签 — 无需构建工具 |

推荐搭配

如果你还需要 会话录制和用户行为回放,可以看看 sigillum-js —— 轻量级会话录制库。

aemeath-js(日志 & 监控)+ sigillum-js(会话录制)= 完整的前端可观测性方案,所有数据都在你自己的服务器上。

反馈

欢迎提交 Issue 和功能建议!请到 Issues 页面反馈。

许可证

MIT © TieriaSail


本项目使用 AI 辅助开发。