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

aegis-uni-sdk

v1.39.5

Published

腾讯云 Aegis(RUM) 前端监控的 uni-app 全端 SDK:微信小程序自动走官方 aegis-mp-sdk,H5 / App / 支付宝 / 抖音 / 快手 / 京东走协议逐字段对齐的自研实现,业务代码零条件编译。

Readme

aegis-uni-sdk

npm version license

腾讯云 Aegis(RUM 前端性能监控)的 uni-app 全端 SDK。

腾讯官方只提供 aegis-mp-sdk(微信 / QQ 小程序)和 aegis-web-sdk(Web),uni-app 项目一旦要同时发 H5、App、支付宝 / 抖音 / 快手 / 京东小程序,就没有一个包能全端覆盖。

本包解决这件事:

  • 微信小程序 → 自动使用官方 aegis-mp-sdk,白拿崩溃 / 卡顿 / 白屏 / 内存等私有能力
  • 其余各端 → 自动使用自研实现,上报协议与官方 [email protected] 逐字段对齐(同一份数据落到同一个看板,维度可横向比较)
  • 业务代码零条件编译,一行接入,不需要知道自己跑在哪个端

分流在编译期由 uni-app 的条件编译完成,所以各端产物只含自己那一份实现:微信端不含自研代码,其余端完全不引入 aegis-mp-sdk


安装

pnpm add aegis-uni-sdk
# npm i aegis-uni-sdk / yarn add aegis-uni-sdk

aegis-mp-sdk 是本包的依赖,无需单独安装。

快速开始

// App.vue
import { installAegis } from "aegis-uni-sdk";

onLaunch(() => {
  installAegis({
    id: "你的上报 id", // aegis 控制台分配
    version: "3.4.8", // 应用版本,强烈建议传,否则看板「版本」维度会回落成 SDK 版本号
  });
});

挂好之后全项目可用:

uni.$aegis?.report({ msg: "下单失败", ext1: `orderNo=${orderNo}` });
uni.$aegis?.reportEvent({ name: "click_submit" });
uni.$aegis?.reportTime("home_first_screen", 1200);

类型提示

在项目 tsconfig.json 里加一条,uni.$aegis 全项目就有类型了:

{
  "compilerOptions": {
    "types": ["aegis-uni-sdk/types"]
  }
}

登录后回填用户标识

const aegis = installAegis({ id: "xxx" });
// 拿到用户信息之后
aegis.setConfig({ uin: userId });
// 或者 uni.$aegis?.setConfig({ uin: userId });

平台支持

| 平台 | 支持 | 实现 | | ------------------------- | :--: | ------------------------------------------------------------------------------- | | 微信小程序 | ✅ | 官方 aegis-mp-sdk | | H5 / Web | ✅ | 自研 | | App(Android / iOS) | ✅ | 自研 | | App 鸿蒙(app-harmony) | ✅ | 自研 | | 支付宝小程序 | ✅ | 自研 | | 抖音小程序 | ✅ | 自研 | | 快手小程序 | ✅ | 自研 | | 京东小程序 | ✅ | 自研 | | QQ 小程序 | ⚠️ | 走自研分支。官方 SDK 支持 QQ,但本包目前只对 MP-WEIXIN 分流,需要的话提 issue | | 百度小程序 | ✅ | 自研(未实测,理论可用) |


★ 微信端与其余端的差异

两端共有的能力(业务可以放心跨端调用):

| 能力 | 说明 | | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | 自定义上报 report | POST /collect | | 普通日志 info / infoAll | 同上,level 不同 | | 错误上报 error | 同上 | | 自定义事件 reportEvent | POST /collect/events | | 自定义测速 reportTime / reportT / time / timeEnd | POST /speed/custom | | PV 转发 reportPv | GET /collect/{id} | | 动态配置 setConfig | 登录后回填 uin 等 | | 销毁 destroy | | | bean 全维度 | id uin aid version env sessionId referer platform netType model vp sr from + ext1~3 | | 聚合上报 / 日志去重 / 超长截断 / 采样 / 失败熔断 | 见「可靠性机制」 |

只有微信端有的能力(官方 SDK 私有,依赖微信专有 API,自研无法实现):

| 能力 | 官方配置项 | 为什么自研做不到 | | ----------------------------------- | ------------------------------- | -------------------------------------------------------------- | | 崩溃监控 | crashMonitor | 依赖 wx.onAppHide + 存储的崩溃指纹推断,非微信端没有等价语义 | | 卡顿 / 无响应监控 | lagMonitor | 依赖微信 setData 耗时与渲染层信号 | | 白屏检测 | blankScreen | 依赖 createSelectorQuery() 查询渲染层节点 | | 内存告警 | memoryMonitor | 依赖 wx.onMemoryWarning | | 分包加载测速 | reportLoadPackageSpeed | 依赖微信分包加载生命周期 | | 接口自动测速 | reportApiSpeed | 需要劫持 wx.request,见下方「未实现」 | | 自动 PV | spa | 需要劫持路由生命周期,见下方「未实现」 | | trace header 注入 | api.injectTraceHeader | 需要劫持 wx.request | | gzip 压缩上报 | gzip | 需要引入 pako,收益不足以换体积 | | 远程采样白名单 | whiteListUrl / rateLimitUrl | 服务端下发,见下方「未实现」 | | 页面性能 / webVitals / setData 上报 | pagePerformance 等 | 依赖微信性能 API |

⚠️ 本包默认把官方的 reportApiSpeedspa 关掉。原因:自研实现没有对应能力,开着会让微信端与其余端的数据无法横向比较。想开就显式打开(见下)。

给微信端传官方专属配置

通用配置对所有端生效;微信独有的选项走 mpWeixin 透传,其余端会忽略:

installAegis({
  id: "xxx",
  version: "3.4.8",
  // 只有微信端会用到,其余端自动忽略
  mpWeixin: {
    crashMonitor: true,
    lagMonitor: { threshold: 2000 },
    blankScreen: { contentSelectors: [".page-container"] },
    reportApiSpeed: true, // 覆盖本包的默认关闭
  },
});

★ 未实现的能力

自研实现(即非微信端)没有下列能力,微信端仍由官方 SDK 提供:

| 未实现 | 原因 | | -------------------------------------------------- | --------------------------------------------------------------------------------------- | | gzip 压缩上报 | 需引入 pako;官方也只在 payload > 1KB 时压缩,收益不足以换体积 | | 远程采样白名单 /collect/whitelist/rateConfig | 由服务端下发采样率与白名单,属于服务侧策略。本包只实现本地会话级采样(random) | | 白屏检测 | 依赖 createSelectorQuery() 查询渲染层节点,其余端无等价能力 | | 卡顿 / 无响应监控 | 依赖微信渲染层信号 | | 崩溃监控 | 依赖微信生命周期指纹推断 | | 内存告警 | 依赖 wx.onMemoryWarning | | trace header 注入 | 需劫持 uni.request,会与业务自己的请求拦截器打架,交由使用方决定 | | 离线日志 /offline | 需要本地日志库与回捞通道 | | 页面性能 / webVitals / hippy 性能 | 依赖各端差异极大的性能 API | | 自动接口测速 | 需劫持 uni.request,同上。已留好 reportTime(),想接就在自己的请求拦截器里调一行 | | 自动 PV | 需劫持路由生命周期。已留好 reportPv(),想接就在页面 onShow 里调 |

后两项是有意留给使用方的:uni-app 项目通常已经有自己的请求拦截器与路由拦截器,由 SDK 再劫持一次容易冲突。


API

installAegis(options) / createAegis(options)

两者都返回上报实例;installAegis 会额外把实例挂到 uni.$aegis

配置项

| 字段 | 类型 | 默认 | 说明 | | ---------------- | --------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------- | | id | string | — | 必填,aegis 控制台分配的上报 id | | uin | string \| number | "" | 用户唯一标识,登录后用 setConfig 回填 | | version | string \| number | SDK 版本号 | 应用版本。建议必传,不传会回落成 SDK 版本号(官方行为),看板的版本维度就没意义了 | | env | AegisEnv | others | production / development / gray / pre / daily / local / test / others,非法值回落 others | | hostUrl | string | https://rumt-zh.com | 上报域名 | | delay | number | 1000 | 聚合发送的防抖时长(ms) | | repeat | number | 60 | 同一条日志在 1 分钟窗口内的上报次数上限 | | random | number | 1 | 会话级采样率 [0, 1]1 为全量 | | maxLength | number | 10240 | 单条日志 msg 的最大长度,超出截断 | | pageUrl | string | — | 固定 from 值,传了就不再从页面栈推导 | | ext1 ~ ext10 | string | — | 扩展字段默认值,单条日志上的同名字段优先 | | beforeReport | (log) => log \| boolean \| void | — | 上报前最后一次改写机会,返回 false 丢弃该条 | | onReport | (logs, isErr) => void | — | 上报完成回调 | | mpWeixin | Record<string, any> | — | 仅微信端生效,透传给官方 SDK 构造函数 |

实例方法

| 方法 | level | 说明 | | ------------------------------------------------ | -------------- | ------------------------------------------- | | report(params) | REPORT(2048) | 自定义上报。入参给了 level 就用入参的 | | info(...msg) | INFO(2) | 普通日志,仅白名单用户上报 | | infoAll(...msg) | INFO_ALL(-1) | 普通日志,全量用户上报 | | error(...msg) | ERROR(4) | js 错误。强制覆盖入参 level | | reportEvent(name \| params) | — | 自定义事件 | | reportTime(name, duration) / reportT(params) | — | 自定义测速 | | time(key) / timeEnd(key) | — | 配对计时并自动上报耗时 | | reportPv(id) | — | 把 PV 转发到另一个 aegis id | | setConfig(partial) | — | 动态改配置 | | destroy() | — | 先冲掉缓冲再销毁 |

report / info / infoAll / error 都支持两种调用形态:

aegis.report("多个", "参数", "会用空格拼起来");
aegis.report({ msg: "对象形态", level: LogType.AJAX_ERROR, ext1: "x", trace: err.stack });

只用自研实现(含微信端)

想让所有端行为完全一致(放弃微信端的私有监控能力),直接用子路径:

import { CustomAegis } from "aegis-uni-sdk/custom";

const aegis = new CustomAegis({ id: "xxx" });
// CustomAegis 独有:flush() 立即冲掉缓冲、sessionId 只读属性
aegis.flush();

只要枚举

import { LogType } from "aegis-uni-sdk/log-type";

上报协议

自研实现完全对齐官方 [email protected]。bean 以 querystring 挂在每个上报请求上。

| 用途 | 请求 | Body | | ---------- | ---------------------- | -------------------------------------------------------------------------------------------- | | 普通日志 | POST /collect | 列式 JSON:{level:[...], msg:[...], ext1:[...], count:N}Content-Type: application/json | | 自定义事件 | POST /collect/events | {payload: "[{\"name\":\"...\"}]"} | | 自定义测速 | POST /speed/custom | {payload: "{\"custom\":[{...}]}"} | | PV 转发 | GET /collect/{id} | — |

列式载荷是这个协议最容易踩坑的地方:N 条日志压成「每个字段一个数组」,字段取所有日志的并集,某条缺该字段就补空串,最后带 count

// [{level:"4",msg:"a"}, {level:"2",msg:"b",ext1:"x"}] 会被压成
{ "level": ["4", "2"], "msg": ["a", "b"], "ext1": ["", "x"], "count": 2 }

各字段数组长度必须等于 count,否则服务端按下标对齐时会整体串位。

枚举platform / netType 的未命中值都是 100 而不是 0):

  • platform:android=1 ios=2 windows=3 macos=4 linux=5 devtools=6 other=100
  • netType:wifi=1 2g=2 3g=3 4g=4 5g=5 6g=6 unknown=100
  • LogType:32 项,见 aegis-uni-sdk/log-type

其它细节sessionId = session-{启动时间戳}(进程级常量)· aid 存在本地 AEGIS_ID(与官方同 key,换用本包不会丢设备标识)· refereruni.getLaunchOptionsSync().scene · vp = 视口 宽 * 高sr = 屏幕分辨率 宽 * 高


可靠性机制

自研实现照搬了官方的全套流控,不是「一条日志一个请求」的裸实现:

| 机制 | 行为 | | ---------- | --------------------------------------------------------------------------------------- | | 聚合发送 | 攒够 5 条立即发,否则防抖 delay(1000ms) 后发。错误风暴不会变成请求风暴 | | 按页面分组 | 聚合窗口内跨页的日志会拆成多个请求,各带自己的 from | | 超长截断 | msg 超过 maxLength(10240) 截断 | | 重复限流 | 同一条日志(level + msg 相同)1 分钟窗口内超过 repeat(60) 次丢弃 | | 会话级采样 | random 在会话内只判定一次,命中即整会话上报,避免同一次崩溃的上下文日志被撕成半截 | | 失败熔断 | 连续失败 60 次后停止上报,不再骚扰服务端 | | 就绪队列 | 网络类型未取到时日志先入队(上限 200 条),就绪后一次性冲出,启动期的错误不会缺维度 | | 退后台冲刷 | uni.onAppHide 时立即发出缓冲,最后一批日志不随进程消失 | | 静默失败 | 上报请求带 hideErrorToast 标记,且组装/发送全程 try-catch——监控自己出问题绝不影响业务 |


与官方 SDK 的行为差异

刻意保留 / 刻意修正的几处,都是有原因的:

  1. report 的 level 是默认值,info/infoAll/error 是强制覆盖

    官方 reportObject.assign 末尾不覆盖 level,而 info/error 覆盖——这是个不对称行为。本包照搬,因为业务往往靠 report({ level: LogType.AJAX_ERROR }) 把接口错误投进「ajax 错误」桶。别顺手统一掉,有单测锁着。

  2. from 在日志创建时捕获,不是发送时

    官方在发送时才计算 from,聚合窗口(1s)内若发生页面跳转,日志会被记到新页面上。本包在日志创建时就捕获所属页面,发送时按 from 分组——页面维度更准。用的是官方协议本就支持的 log.from 机制,不是协议偏离。

  3. bean 值统一编码一次

    官方 getBean 直接字符串拼接、不做 encodeURIComponent,遇到 model="iPhone 14 Pro"(含空格)或含 & 的值会污染后续参数。本包在 querystring 组装时统一编码一次。

  4. reportApiSpeedspa 默认关闭

    见上方「微信端与其余端的差异」。


原理与注意事项

端分流是编译期完成的

dist/index.js 长这样(注释就是分流指令):

// #ifndef MP-WEIXIN
import { createCustomReporter } from "./adapters/custom";
// #endif
// #ifdef MP-WEIXIN
import { createMpWeixinReporter } from "./adapters/mp-weixin";
// #endif

uni-app 的条件编译会处理 node_modules 里的代码——它的 uni:pre 插件(@dcloudio/uni-cli-shared)只排除了 vue / vite / vuex / vue-router / vue-i18n 等少数几个包,node_modules 整体并不在排除列表里;H5 的依赖预构建阶段也挂了 uni:dep-scan(esbuild plugin)做同样的事。所以:

  • 微信端产物:只有官方 aegis-mp-sdk,一行自研代码都没有
  • 其余端产物:只有自研实现,完全不引入 aegis-mp-sdk(92KB 一点不占)
  • 零配置,不需要 optimizeDeps.exclude

⚠️ 产物绝对不能 minify

条件编译的载体是注释。一旦产物被压缩或 removeComments: true,指令会被剥掉,分流静默失效——包照样能装能跑,只是微信端把两份实现都打进包、其余端莫名引入 aegis-mp-sdk,且没有任何报错。

所以本仓库:

  • 构建用 tsc 逐文件输出 ESM(保留注释与目录结构),不用 bundler
  • tsconfig.build.jsonremoveComments: false 带着醒目注释
  • pnpm build 末尾跑 scripts/verify-dist.js,用 uni-app 自己那套正则断言产物里的指令完整且配对,CI 也跑

如果你 fork 后想换构建工具,务必保住这条。

依赖 uni-app 运行时

本包直接使用 uni 全局对象(uni.request / uni.getSystemInfoSync / uni.getStorageSync 等)与 getCurrentPages(),只能在 uni-app 项目里用。


版本策略

版本号跟随官方 aegis-mp-sdk1.39.5 表示对齐 [email protected] 的上报协议。这样一眼就知道协议基线是哪一版,也方便判断该不该升。

本包自身的修复会以第四位或预发布号体现,协议基线不变时主版本不动。


开发

pnpm install
pnpm test           # 84 条单测
pnpm typecheck
pnpm lint
pnpm build          # 含产物自检 verify:dist
pnpm check          # 以上全跑

发布

  1. package.jsonversion
  2. 提交
  3. git tag v<version> && git push --tags

GitHub Actions(.github/workflows/release.yml)会校验 tag 与 package.json 版本一致,跑完全部检查后 npm publish --provenance

需要在仓库 Secrets 里配 NPM_TOKEN--provenance 要求仓库为 public,私有仓库请去掉该参数。


License

MIT © liujiayii