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

@arms/rum-browser-nuxt

v0.1.1

Published

Nuxt plugin for @arms/rum-browser SDK (Nuxt 3/4 file-route view tracking + dual-channel error capture, zero nuxt/vue/vue-router imports)

Readme

@arms/rum-browser-nuxt

Nuxt 插件 for @arms/rum-browser RUM SDK —— 支持 Nuxt 3 / Nuxt 4(Vue 3.5+、vue-router v4 / v5)。

能力范围:

  • 文件路由风格的视图追踪:经 router.afterEach 驱动 Shell.startView(手动 view 模式),view.name 反向归一化为 Nuxt 文件路由风格(/user/:id() → /user/[id]),与 pages/ 目录心智一致、聚合稳定
  • Nuxt 双通道异常捕获:链式包装 vueApp.config.errorHandler(保留原 handler)+ nuxtApp.hook('app:error')(Nuxt 启动 / SSR 传播错误),同一错误对象 WeakSet 去重只报一次,自动上报 source: 'vue' 的异常事件(snapshots 内携带 framework: 'nuxt')
  • 手动错误上报:addNuxtError(error, context?) 供 onErrorCaptured / 自定义 errorHandler 场景转发

不含:组件性能监控、hydration 错误分级、Nuxt Module 形态、Nitro 服务端集成(均为非目标,见 docs-dev/browser-nuxt-spec.md)。

安装

本插件不独立工作 —— 需与主包 @arms/rum-browser(必需 peer dependency)同时安装,并完成主包初始化:

npm install @arms/rum-browser @arms/rum-browser-nuxt

发布前置条件

发布顺序(严格按序,前一步发版在 registry 生效后,再发布下一步):

  1. @arms/rum-core@>=0.1.11:含 Shell.startView 与 IConfiguration.trackViewsManually 能力的发版(已在 npm registry 发布)
  2. @arms/rum-browser@>=0.1.16:含 PvCollector 手动模式防护(trackViewsManually 早退,避免双发 PV)的发版(已在 npm registry 发布)
  3. @arms/rum-browser-nuxt(本包)

本包为独立实现(不依赖 @arms/rum-browser-vue / @arms/rum-browser-react,dependencies 为空),无兄弟包解锁约束;peerDependencies 下限与 registry 实际产物对齐,外部安装可正常解析。后续版本迭代仍需遵循上述发布顺序(依赖包发版在 registry 生效后,再发布本包)。仓库内开发期经 workspace 直链源码使用(无需等待发版),安装依赖请遵循仓库惯例使用 yarn 或 scripts/bootstrap.sh。

快速开始

在 Nuxt 项目中创建客户端插件文件(.client.ts 后缀保证仅在客户端执行):

// plugins/arms-rum.client.ts
import ArmsRum from '@arms/rum-browser';
import { initNuxtPlugin } from '@arms/rum-browser-nuxt';

export default defineNuxtPlugin({
  name: 'arms-rum',
  // enforce: 'pre' 保证本插件先于其他插件执行,
  // 错误双通道可捕获后续插件的启动错误
  enforce: 'pre',
  setup() {
    ArmsRum.init({
      endpoint: 'https://your-endpoint',
      // pid: 'your-pid',
    });
    initNuxtPlugin(ArmsRum, {
      router: useRouter(), // 必填:驱动视图采集
      nuxtApp: useNuxtApp(), // 推荐:启用错误双通道
    });
  },
});

时序说明:initNuxtPlugin 不依赖 armsRum.init() 完成 —— 可在 init 前后任意时序同步调用,先后顺序可互换(反向时序经内部 pending 队列兜底,首屏 view 与排队错误不丢失)。defineNuxtPlugin / useRouter / useNuxtApp 均为 Nuxt 自动导入 —— 本包源码零 nuxt / vue / vue-router 导入(SSR-safe),router / nuxtApp 由用户在 setup() 中取好后传入。

视图命名规则

view.name 按 to.matched 尾向头取第一个非空 path(最深匹配段即页面本身的模板),再反向归一化为 Nuxt 文件路由风格:

| vue-router 路由模板(matched.path) | view.name(Nuxt 文件路由风格) | 对应 pages/ 目录 | | -------------------------------------- | ------------------------------ | ------------------------------ | | /users | /users | pages/users.vue | | /user/:id() | /user/[id] | pages/user/[id].vue | | /blog/:slug? | /blog/[[slug]] | pages/blog/[[slug]].vue | | /:slug(.*)* | /[...slug] | pages/[...slug].vue | | /:pathMatch(.*)* | /[...pathMatch] | pages/[...pathMatch].vue | | /users-:group()-:id() | /users-[group]-[id] | pages/users-[group]-[id].vue | | 嵌套路由(父 '' + 子 /user/:id()) | /user/[id](尾向头取最深段) | pages/user/[id].vue |

静态路由原样保留;转义字符还原为字面量(\: → :)。

路由语义

警告:router 必填 —— 传入后 view/PV 完全由 afterEach 驱动,主包自动 PV 被禁用

插件在 nuxtCollector.setup 中注入 trackViewsManually: true:主包 PvCollector 跳过首屏 PV 与 history 拦截(避免双发),view 的创建、命名、计时完全依赖 router.afterEach 驱动(内部调用 shell.startView)。

导航语义(对齐 Nuxt 场景约定):

| 导航场景 | 是否开新视图 | 说明 | | ------------------------------------ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | 首次导航 / 首屏 | ✅ | initial_load;init 前触发经 pending 队列补发 | | 路径变化 | ✅ | route_change(ctx 已有 view 时;否则 initial_load) | | query 变化(path 与 hash 不变) | ❌ 跳过 | /list?page=1 → /list?page=2 不算新视图 | | hash 变化(path 不变) | ❌ 去重 | /doc#section-a → /doc#section-b afterEach 放行但视图名不变,经 Shell.startView 同名去重后无新 view 事件(与 browser-vue 行为一致) | | 导航失败(afterEach 第三参 failure) | ❌ 跳过 | guard 拦截 / 取消等不算新视图 | | 同名重复导航 | ❌ 去重 | Shell.startView 内建同名去重 |

异常捕获说明

nuxtApp 传入时启用双通道自动接管:

  • 通道 1:链式包装 nuxtApp.vueApp.config.errorHandler —— 先经 addNuxtError 上报,再调用你已有的 handler(保留 Nuxt 自带 handleVueError 驱动错误页的行为;无原 handler 时保持 Vue 默认的 console.error 可见性,不吞错)
  • 通道 2:nuxtApp.hook('app:error') 捕获 Nuxt 启动 / SSR 传播错误(纯 Vue 场景不存在的 Nuxt 独有通道;插件 enforce: 'pre' 时可捕获后续插件启动错误)
  • 去重:同一错误对象(引用相等)经双通道只报一次(WeakSet);非 object 错误值无引用语义,不去重

上报字段:

{
  event_type: 'exception',
  type: 'error',
  source: 'vue',                 // 复用家族 vue 错误存储/查询链路
  name: 'TypeError',             // error.name(非 Error 值自动 normalize)
  message: "Cannot read properties of undefined",
  stack: '...',
  // 扩展信息收敛为单一 JSON 字符串字段(值为 undefined 的内部键不会出现)
  snapshots: JSON.stringify({
    handling: 'handled',
    framework: 'nuxt',           // 本包标识,恒定携带
    component_stack: 'at <OrderList>\nat <UserPage>',  // 当前组件在前,沿父链向上
    component_name: 'OrderList',
    lifecycle_hook: 'hook:mounted',  // Vue errorHandler 的 info 参数
  }),
  times: 1,
}

也可在 onErrorCaptured / 自定义 errorHandler 中手动上报(双通道已接管时无需重复调用):

import { addNuxtError } from '@arms/rum-browser-nuxt';

// 组件内
onErrorCaptured(function (err, instance, info) {
  addNuxtError(err, { lifecycle_hook: info });
  return false;
});

API

主入口 @arms/rum-browser-nuxt(单入口,无子入口)

| 导出 | 说明 | | ---------------------------------------------------------- | ---------------------------------------------------------------------------------- | | initNuxtPlugin(shell: Shell, options: NuxtPluginOptions) | 初始化插件(collector 注册 + 路由视图采集 + 条件启用错误双通道) | | addNuxtError(error: unknown, context?: NuxtErrorContext) | 手动上报 Nuxt 异常(component_stack / component_name / lifecycle_hook 可选) | | type NuxtPluginOptions / NuxtErrorContext 等 | 公共类型(duck typing,版本无关) |

NuxtPluginOptions

initNuxtPlugin(shell, options) 的第二参数(源 src/types/index.ts):

| 字段 | 类型 | 必填 | 说明 | | --------- | ------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | router | AnyRouter | 是 | vue-router 实例(v4 / v5 均可,useRouter() 取得,仅依赖 afterEach / currentRoute 最小接口)。驱动 view 生命周期(手动 view 模式:注入 trackViewsManually + 调用 Shell.startView) | | nuxtApp | NuxtAppLike | 否 | NuxtApp 实例(useNuxtApp() 取得)。提供时启用错误双通道自动接管;不提供时仅启用路由视图采集,错误可经 addNuxtError 手动上报 |

NuxtErrorContext

addNuxtError 的第二参数(字段对齐 @arms/rum-browser-vue 的 VueErrorContext):

| 字段 | 类型 | 说明 | | ----------------- | -------- | ----------------------------------------------------------------------------------- | | component_stack | string | 组件链栈,如 'at <OrderList>\nat <UserPage>'(当前组件在前) | | component_name | string | 出错组件名 | | lifecycle_hook | string | 生命周期钩子 / 错误来源信息(Vue errorHandler 的 info 参数,如 'hook:mounted') |

版本要求

| 依赖 | 版本要求 | 说明 | | ------------------- | -------------------- | ------------------------------------------------------------------------------------------------ | | @arms/rum-core | >=0.1.11 | 含 Shell.startView 与 IConfiguration.trackViewsManually(已发布) | | @arms/rum-browser | >=0.1.16 | 含 PvCollector 手动模式防护(已发布) | | nuxt | 3(>=3.7)\|\| 4 | optional peer;3.7 起 defineNuxtPlugin 对象语法与 enforce 稳定 | | vue | ^3.5.0 | optional peer;本包经 nuxtApp.vueApp.config.errorHandler duck typing 访问,不直接依赖 vue 模块 | | vue-router | ^4.0.0 \|\| ^5.0.0 | optional peer;仅依赖 afterEach / currentRoute 最小接口 |

版本口径说明:peerDependencies 中 nuxt 声明为 3 || 4,实际支持基线为 Nuxt ≥3.7 —— 更早版本的 defineNuxtPlugin 对象语法与 enforce 不稳定。vue peer 为 ^3.5.0,而 Nuxt 3.7-3.12 生态常配 vue 3.3 / 3.4 —— 三项框架 peer 均 optional(peerDependenciesMeta 标记),版本不满足仅产生安装告警、不阻塞安装(插件对框架实例 duck typing,实际兼容宽于声明口径)。

Nuxt 2 用户

Nuxt 2 / Vue 2 已 EOL(插件体系完全不同),本包不支持。请使用通用包 @arms/rum-browser(自动 PV + 全局异常采集,无 Nuxt 专属能力),或升级到 Nuxt 3 后接入本包。

已知限制

以下限制是当前 MVP 设计所固有的,后续版本计划改进。

单实例约束

插件为 collector 级单例(模块级状态持有 shell / ctx 引用)。重复调用 initNuxtPlugin 传入另一个 rum 实例时会打印 logger.warn 并跳过重复注册、仅刷新 shell 引用 —— 最后一次绑定的实例生效。微前端多子应用各自持有独立 RUM 实例的场景暂不支持。

source='vue' 错误不受 collectors.jsError 采样管控

本包上报的错误携带 source: 'vue',browser SDK 的 SessionProcessor 采样键映射当前不覆盖 'vue'(与 browser-vue 包同款已知约束)——这些错误会绕过 collectors.jsError 采样配置。如需禁用,请使用 collectors.exception(设置为 false)。另外,core reporter 对 exception 按 getErrorID(message + stack) 聚合且 key 不含 source —— 同一错误被全局通道与插件双通道捕获时会聚合合并;自动通道错误可经 filters.exception 过滤以保留富上下文事件。

errorHandler 覆盖边界

  • 组件 onErrorCaptured 返回 false:按 Vue 语义该错误被视为"已处理"并阻止传播,全局 errorHandler 不会触发 —— 插件捕获不到(Vue 框架行为);需观测时请在 onErrorCaptured 中手动调用 addNuxtError;
  • warnHandler 不覆盖:Vue 运行时警告不进入 RUM 异常事件;
  • unhandledrejection:由主包 @arms/rum-browser 的 jsError 采集器覆盖,无需本插件处理;
  • hydration mismatch 明细:Vue errorHandler 不捕获(vuejs/core#13154),不做监控承诺。

错误页为全新页面加载

Nuxt 渲染 error.vue 属全新页面加载,插件与会话上下文随之重置 —— 错误后首屏 view 重新计为 initial_load。

无 pages/ 目录的应用

仅单 app.vue 的 Nuxt 应用没有路由实例,插件因缺少有效 router 整体禁用(logger.error 自监控上报),仅 addNuxtError 手动错误上报可用。

错误去重窗口语义

双通道去重按 app 生命周期(WeakSet 按错误对象引用)—— 同一 Error 实例二次抛出会被去重丢弃。

初始化时序

initNuxtPlugin 可在 armsRum.init() 前后任意时序同步调用。初始化完成之前调用 addNuxtError 时安全降级:插件未接入则 warn + skip(不抛错);插件已接入但 init 未完成则排队,init 完成后自动补发。init 前触发的路由导航经 pending 队列兜底,collector setup 后自动补发首个 view(loading_type: 'initial_load'),首屏不丢失。

兼容性

| 环境 | 支持情况 | 说明 | | --------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Vite / webpack 5 等 | ✅ | 经 exports 字段解析单入口(types / import / require / default 四条件) | | SSR(Nuxt 服务端) | ✅ 安全 | 源码零 nuxt / vue / vue-router 导入、零顶层 window / document 访问(唯一 DOM 触点 getCurrentUrl 在函数内 try-catch 防护);配合 .client.ts 后缀约定使用 | | CDN / <script> 标签 | ❌ 不适用 | 本包不出 UMD dist 产物,仅经 bundler 消费 —— CDN 场景请直接使用主包 @arms/rum-browser |

产物压缩说明:es / lib 产物已经过 terser 压缩与混淆,且不附带 sourcemap(与 browser-vue / browser-nextjs 包一致的体积/混淆 trade-off)。排查线上堆栈时请对照仓库源码与 CHANGELOG 版本定位对应发布版本。