Vue 应用接入 ARMS RUM,分别采集 JS 错误、业务异常和业务事件,并通过 SourceMap 将压缩堆栈还原到源码。
配套代码:ARMS-SourceMap-Demo。
环境与工程准备
准备 Node.js 20/22、Go 和目标 RUM 应用。获取应用接入用的 PID、Endpoint,以及符号表上传所需的工作空间、Service ID、地域和构建凭据。
git clone https://github.com/Roliyal/CROlordCodelibrary.git
cd CROlordCodelibrary/Chapter6Custom/ARMS-SourceMap-Demo/frontend
npm install
npm install vue @arms/rum-browser
npm install -D @arms/rum-vite-plugin仓库是基础示例,原有构建插件配置使用旧字段。采用当前插件时,按第 4 步更新上传配置;不要直接复用旧地域默认值。
| 情况 | 处理方式 | 用途 |
|---|---|---|
| 未处理的运行时错误 | SDK 异常采集 | 定位代码故障 |
| 已被业务捕获的异常 | sendException |
记录明确需要排查的业务失败 |
| 提交、购买、搜索等业务行为 | sendCustom |
统计行为与业务结果 |
库存不足、用户取消等正常分支,不必全部记为系统错误。先定清事件语义,错误数量和告警才有参考价值。
填写前端配置并初始化 SDK
在 frontend/.env.local 配置浏览器接入参数:
VITE_ARMS_RUM_PID=<目标RUM应用PID>
VITE_ARMS_RUM_ENDPOINT=<浏览器上报地址>
VITE_APP_VERSION=rum-demo-001修改后重启开发服务,使构建变量生效。
示例使用 @arms/rum-browser,在创建 Vue 应用前初始化一次:
import armsRum from '@arms/rum-browser'
import { createApp } from 'vue'
import App from './App.vue'
armsRum.init({
pid: import.meta.env.VITE_ARMS_RUM_PID,
endpoint: import.meta.env.VITE_ARMS_RUM_ENDPOINT,
env: import.meta.env.MODE,
appVersion: import.meta.env.VITE_APP_VERSION
})
createApp(App).mount('#app')应用标识和上报地址从目标 RUM 应用获取。发布版本使用构建号或提交版本,避免线上多个构建都叫 dev。
采集器参数随 SDK 版本可能变化,接入时应固定依赖并核对该版本文档。Vue 框架内捕获的错误也要检查是否已接入采集;不能默认所有组件错误都会冒泡为浏览器未处理异常。手动上报前先确认现有集成,避免同一错误记录两次。
给页面加上三个测试按钮
在 src/App.vue 分别触发三种记录:
<script setup>
import armsRum from '@arms/rum-browser'
function throwJsError() {
setTimeout(() => {
throw new Error('RUM_SOURCEMAP_TEST')
}, 0)
}
function sendBizException() {
armsRum.sendException({
name: 'ORDER_CREATE_FAILED',
message: '订单创建失败',
properties: { stage: 'submit', reason: 'upstream_timeout' }
})
}
function sendBizEvent() {
armsRum.sendCustom({
type: 'biz', name: 'order_submit', group: 'order', value: 1,
properties: { result: 'failed' }
})
}
</script>
<template>
<main>
<button @click="throwJsError">触发 JS 错误</button>
<button @click="sendBizException">上报业务异常</button>
<button @click="sendBizEvent">上报业务事件</button>
</main>
</template>setTimeout 中的错误用于测试浏览器未处理异常,避免被 Vue 的组件错误处理先行捕获。
sendException 需要 name、message;sendCustom 需要 type、name。自定义事件进入事件统计,不能到异常列表里找。
事件属性保留用于聚合的稳定字段,不上传密码、Cookie、完整请求头或未经处理的个人信息。异常名也不要拼接用户 ID、订单号等不断变化的内容。
构建 SourceMap,并上传到同一应用
Vite 需要生成独立 SourceMap:
export default defineConfig({
plugins: [vue()],
build: { sourcemap: 'hidden' }
})hidden 不会在 JS 中留下 SourceMap 引用,但 .map 仍会生成。应将它上传到 RUM,并从公开发布的静态资源中排除;仅设置 hidden 不会自动阻止公网访问。
在 vite.config.js 配置自动上传。下列值从 CI 环境变量获取,APP_VERSION 与浏览器应用版本对应:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { rumVitePlugin } from '@arms/rum-vite-plugin'
export default defineConfig({
plugins: [
vue(),
rumVitePlugin({
workspace: process.env.RUM_WORKSPACE,
serviceId: process.env.RUM_SERVICE_ID,
region: process.env.RUM_REGION,
version: process.env.APP_VERSION,
accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
stsToken: process.env.ALIBABA_CLOUD_SECURITY_TOKEN,
clearSourceMap: true
})
],
build: { sourcemap: 'hidden' },
server: {
proxy: {
'/api': { target: 'http://127.0.0.1:8080', changeOrigin: true }
}
}
})使用 RUM 构建插件时,要按已安装版本配置目标应用、地域、发布版本和构建环境凭据。插件负责注入关联标识,并在正确配置上传后处理符号表。旧版示例里的 pid 配置,不能不经核对就套到新版插件上。
上传凭据只放在本地构建环境或 CI 密钥配置里,不能使用会进入浏览器产物的 VITE_ 变量保存 AccessKey Secret。
启动服务与验证
需要联调 /api/hello 时,在独立终端运行仓库的 Go 后端:
cd CROlordCodelibrary/Chapter6Custom/ARMS-SourceMap-Demo/backend
go run .
curl -fsS http://127.0.0.1:8080/healthz前端在配置好构建环境变量后执行:
npm run build
npm run preview -- --host 127.0.0.1访问终端输出的预览地址,逐个点击测试按钮。
开发服务器下的源码堆栈,不能替代生产构建验收。应使用真正准备发布的 JS 与 SourceMap 做检查:
- 构建并确认 SourceMap 生成、关联标识注入和上传结果。
- 部署同一次构建的静态资源,确认 RUM 应用和版本一致。
- 在测试环境触发一个带堆栈的错误。
- 打开 RUM 异常详情,检查能否还原到源码文件和行列位置。
- 分别发送自定义异常和事件,核对它们进入各自的列表。
常见问题
上传成功却没有源码时,检查应用、地域、版本、debugId 及 sourcesContent。这些信息必须对应同一次构建,不能上传旧版本的 .map 再验证新版本 JS。
另一个容易混淆的问题是 Vite 代理:server.proxy 用于开发服务器。把 dist 交给静态服务器后,生产 /api 路由还需要由网关或 Web 服务器配置。
前后端 Trace 关联可以在上述验收通过后再接入,排障时更容易区分异常采集、源码还原和链路传播三个问题。