aemeath-js
v1.7.0
Published
A modular, type-safe logging system with plugin architecture
Maintainers
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-jsyarn 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+ | 服务端堆栈解析 |
| 核心 / 插件 | 仅浏览器 | 依赖 window、document |
构建工具
| 工具 | 支持版本 | 集成方式 | |------|---------|----------| | 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 辅助开发。
