关于 upgrade-browser-sdk-v7
用于将 Datadog Browser SDK 项目从 v6 升级到 v7 的分步迁移技能,涵盖代码检索、API 变更、行为差异及基础设施检查。
主要功能
- 01更新 CDN 和 npm SDK 版本
- 02查找弃用选项及变更的 API
- 03检查行为变化与迁移措施
- 04搜索代码中的受影响用法
适用场景
- 01规划 Browser SDK 从 v6 升级到 v7
- 02定位过时的初始化选项
- 03更新依赖 RUM 或 Logs API 变更的代码
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ datadog-labs/ agent-skills --skill upgrade-browser-sdk-v7安装后在 Claude Code 中输入/upgrade-browser-sdk-v7确认已加载。
详细介绍
将 Datadog Browser SDK 升级到 v7
从 v6 迁移到 v7 的系统性指南。请按顺序完成步骤 1-6。每个步骤都包含用于查找受影响代码的搜索模式。
步骤 1:更新 SDK 版本
CDN 配置 — 更新脚本 src URL:
| v6 模式 | v7 替换项 |
|---|---|
datadoghq-browser-agent.com/us1/v6/datadog-rum.js | datadoghq-browser-agent.com/us1/v7/datadog-rum.js |
datadoghq-browser-agent.com/us1/v6/datadog-logs.js | datadoghq-browser-agent.com/us1/v7/datadog-logs.js |
datadoghq-browser-agent.com/us1/v6/datadog-rum-slim.js | datadoghq-browser-agent.com/us1/v7/datadog-rum-slim.js |
将 us1 替换为你的站点:eu1、us3、us5、ap1、ap2。对于 US1-FED,模式为扁平格式,不带站点前缀:datadog-rum-v7.js、datadog-logs-v7.js、datadog-rum-slim-v7.js。
搜索:grep -r "datadoghq-browser-agent.com.*v6" --include="*.html" --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx"
npm 配置 — 更新 package.json 依赖项:
"@datadog/browser-rum": "^7.0.0"
"@datadog/browser-logs": "^7.0.0"
"@datadog/browser-rum-slim": "^7.0.0"
然后运行你的包管理器(npm install、yarn install 等)并重新构建。
同时将框架集成升级到 v7:@datadog/browser-rum-react、@datadog/browser-rum-angular、@datadog/browser-rum-vue、@datadog/browser-rum-nextjs。
搜索:grep -r "@datadog/browser-" --include="package.json" .
步骤 2:添加 crossorigin="anonymous"(仅限 CDN)
v7 CDN 包使用 ESM 动态导入。加载 SDK 的每一个 <script> 标签都必须包含 crossorigin="anonymous":
<script src="https://www.datadoghq-browser-agent.com/us1/v7/datadog-rum.js" crossorigin="anonymous"></script>
对于动态创建的脚本元素:
const script = document.createElement('script')
script.crossOrigin = 'anonymous' // Must set BEFORE setting src
script.src = 'https://www.datadoghq-browser-agent.com/us1/v7/datadog-rum.js'
搜索:grep -rn "datadoghq-browser-agent" --include="*.html" --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx"
检查每个匹配项是否包含 crossorigin 属性(HTML)或 .crossOrigin 属性(JS)。
步骤 3:移除已弃用的选项
在初始化调用中搜索以下选项,并应用相应替换:
从 Core 中移除(影响 RUM 和 Logs)
| 选项 | 操作 |
|---|---|
betaEncodeCookieOptions | 删除。始终启用 Cookie 编码。 |
allowFallbackToLocalStorage | 替换为 sessionPersistence: ['cookie', 'local-storage'] |
从 RUM 中移除
| 选项 | 操作 |
|---|---|
trackBfcacheViews | 删除。始终跟踪 BFCache 视图。 |
trackEarlyRequests | 删除。始终收集早期请求。 |
betaTrackActionsInShadowDom | 删除。始终启用 Shadow DOM 操作跟踪。 |
从 Logs 中移除
| 选项 | 操作 |
|---|---|
usePciIntake | 删除。标准接收端现已符合 PCI 标准。如果你已将 PCI 专用域名加入允许列表,请更新 CSP。 |
搜索:grep -rn 'betaEncodeCookieOptions\|allowFallbackToLocalStorage\|trackBfcacheViews\|trackEarlyRequests\|betaTrackActionsInShadowDom\|usePciIntake' --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" --include="*.html" --include="*.vue" --include="*.svelte"
步骤 4:更新已更改的 API
4a. forwardErrorsToLogs + forwardConsoleLogs(日志)
这两个选项现在相互独立。在 v6 中,forwardErrorsToLogs: true 会产生一个副作用:同时将 console.error() 调用转发到日志。在 v7 中,这个副作用已移除。
forwardErrorsToLogs— 控制是否将未处理的错误(未捕获的异常、未处理的拒绝)和网络错误转发到日志。保持不变。forwardConsoleLogs— 控制是否将console.error()调用转发到日志。要恢复 v6 中的副作用,请在此处添加'error'。
只有在 forwardErrorsToLogs 为 true 或被省略时,才添加 forwardConsoleLogs: ['error']——在 v6 中,只有启用此选项时(显式启用或使用默认值),才会产生该副作用。如果 forwardErrorsToLogs: false,则无需恢复副作用;保持不变。
// v6 — forwardErrorsToLogs: true (explicit or omitted, which defaults to true)
DD_LOGS.init({
forwardErrorsToLogs: true,
forwardConsoleLogs: ['warn'], // example: existing levels
})
// v7 — add 'error' to restore the side effect; preserve any existing levels
DD_LOGS.init({
forwardErrorsToLogs: true, // unchanged
forwardConsoleLogs: ['warn', 'error'], // add 'error'
})
// v6 — forwardErrorsToLogs: false → no side effect existed; nothing to add
DD_LOGS.init({
forwardErrorsToLogs: false, // leave unchanged, do NOT add forwardConsoleLogs: ['error']
})
不要用 forwardConsoleLogs 替换 forwardErrorsToLogs——它们控制的内容不同。
搜索显式配置:grep -rn "forwardErrorsToLogs" --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" --include="*.html" --include="*.vue" --include="*.svelte"
同时搜索可能依赖默认值的日志初始化调用(v6 中 forwardErrorsToLogs 的默认值为 true,因此省略此选项仍会产生该副作用):grep -rn "DD_LOGS\.init\|datadogLogs\.init" --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" --include="*.html" --include="*.vue" --include="*.svelte"
对于任何 forwardErrorsToLogs 为 true 或被省略,且 forwardConsoleLogs 尚未包含 'error' 或 'all' 的日志初始化调用,请添加 'error',以保留 v6 中的行为。
4b. startDurationVital / stopDurationVital(RUM)
DurationVitalReference 对象已替换为 vitalKey 字符串。startDurationVital 现在返回 void——v7 API 采用即发即弃方式;只需提供体征名称字符串。
// v5/v6 — ref-based (CDN: DD_RUM, npm: datadogRum)
var ref = DD_RUM.startDurationVital('checkout_flow')
// ... async work ...
DD_RUM.stopDurationVital(ref)
// v7
DD_RUM.startDurationVital('checkout_flow', { vitalKey: 'checkout_flow' })
DD_RUM.stopDurationVital('checkout_flow', { vitalKey: 'checkout_flow' })
**这会在 CDN/纯 JS 项目中悄无声息地造成问题。**TypeScript 会通过类型错误检测到问题;纯 JS 则不会。ref 会变为 undefined,而 stopDurationVital(undefined) 不会执行任何操作——体征启动后却永不停止,因此不会发出事件。
步骤 1 — 查找所有 startDurationVital/stopDurationVital 用法(包括 CDN 和 npm 模式,以及所有文件类型):
grep -rn 'startDurationVital\|stopDurationVital\|DurationVitalReference' \
--include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" \
--include="*.html" --include="*.svelte" --include="*.vue"
步骤 2 — 查找所有接收返回值的变量(这是出错的关键点):
grep -rEn '(var|const|let)\s+\w+\s*=\s*.+startDurationVital|[\w.]+\s*=\s*(window\.)?DD_RUM\.startDurationVital|[\w.]+\s*=\s*datadogRum\.startDurationVital' \
--include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" --include="*.html" \
--include="*.svelte" --include="*.vue"
对于每个匹配项:移除变量赋值,并在相应的 stopDurationVital 调用中,将该变量的所有用法改为直接传入体征名称字符串。
步骤 3 — 如果 SDK 封装在工具函数中(例如 startTiming / stopTiming):
- 更新封装函数——将
vitalKey传给startDurationVital,不返回任何内容。 - 查找接收封装函数返回值的调用方:
grep -rEn '(var|const|let)\s+\w+\s*=\s*.+[Ss]tart[Tt]iming|(var|const|let)\s+\w+\s*=\s*.+[Ss]tart.+[Vv]ital' \
--include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" \
--include="*.html" --include="*.svelte" --include="*.vue"
- 移除返回值接收操作,并更新停止调用,改为直接传入体征名称字符串:
// Caller — before
var ref = startTiming('checkout_flow')
stopTiming(ref) // undefined in v7 → vital never stops
// Caller — after
startTiming('checkout_flow')
stopTiming('checkout_flow')
4c. 插件 API:已移除 strategy(RUM)
插件 API 中已移除 strategy 字段。如果你使用 @datadog/browser-rum-react 或其他插件集成,请将它们升级到 v7。
搜索:grep -rn "strategy" --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx"(查找插件定义)
步骤 5:检查行为变更(无需修改代码,但可能需要留意)
以下是默认值变更——不会导致代码出错,但行为与 v6 不同:
| 变更 | 影响 | 如有需要采取的操作 |
|---|---|---|
defaultPrivacyLevel 默认为 "mask-user-input"(原为 "mask") | 默认遮蔽限制较宽松。仅遮蔽用户输入。 | 设置 defaultPrivacyLevel: "mask" 以保留完整遮蔽。 |
enablePrivacyForActionName 默认为 true | 操作名称根据 textContent(而非 innerText)生成——不再应用 CSS text-transform。在 v6 中,带有 style="text-transform: capitalize" 且原始文本为 "audio" 的按钮会生成 "Audio",而在 v7 中会生成 "audio"。名称也可能根据隐私级别进行遮蔽。**注意:**将此项设为 false 不会恢复对 CSS 的识别提取——v7 始终使用 textContent。 | 为显示名称依赖 CSS 转换的元素添加 data-dd-action-name 属性,或更新监控以匹配原始文本值。使用 Datadog 构建插件进行基于注解的控制。 |
propagateTraceBaggage 默认为 true | CORS:跨域 API 必须允许 baggage 请求头。 | 将 "baggage" 添加到 Access-Control-Allow-Headers,或设置 propagateTraceBaggage: false。 |
| 确定性采样 | 根据会话 ID 和采样率计算采样结果,而非存储采样结果。不同页面间保持一致。 | 如果不同页面使用不同的采样率,请进行检查。 |
| 移除 FID | 不再采集首次输入延迟。 | 改用 INP(交互到下一次绘制)。 |
session_renewal 视图加载类型 | 会话续期后的视图将使用 @view.loading_type:session_renewal,而非 route_change。 | 更新按 @view.loading_type 筛选的仪表板/监控。 |
文档资源的 initiatorType 已更改 | "initial_document" 变为 "navigation"。持续时间可能略有差异。 | 更新检查文档资源 performanceEntry 的代码。 |
| 操作名称可能变化 | v7 始终使用树遍历和 textContent(包括 Shadow DOM)——无论 enablePrivacyForActionName 的设置如何,都不会反映 CSS text-transform。对视觉转换后的名称进行区分大小写筛选的监控可能会失效。 | 为受影响的元素添加 data-dd-action-name 属性,或更新监控以匹配原始文本值。 |
| 移除已取消请求的错误(日志) | 已中止的 fetch/XHR 不再生成网络错误日志。 | 无需操作——可减少噪声。 |
| Logs 始终需要会话存储 | 如果没有 Cookie 或 localStorage,Logs SDK 将不会启动。 | 在 Worker 环境中使用 sessionPersistence: 'memory'。 |
| Session Replay:变更记录 | 新的序列化格式。更准确,占用带宽更少。 | 如果依赖原始片段格式,请进行更新。 |
异步分块名称添加了 datadog 前缀 | 例如:datadogRecorder-<hash>-datadog-rum.js、datadogProfiler-<hash>-datadog-rum.js。 | 更新 CSP script-src 规则或缓存配置(允许 datadog*-datadog-rum.js)。 |
步骤 6:更新基础设施
- CSP:
- 在 script-src 中添加
crossorigin。 - 更新分块名称,例如
datadog*-datadog-rum.js(如datadogRecorder、datadogProfiler)。 - 如果移除了
usePciIntake,请更新 CSP,使其适用于标准 intake 域名。
- 在 script-src 中添加
- Cookie:将
_dd_s_v2添加到 Cookie 允许列表中。SDK 会在首次加载时自动从_dd_s迁移。回滚到 v6 会启动新会话。 - CORS:搜索追踪配置:
grep -rn "allowedTracingUrls\|propagateTraceBaggage" --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" --include="*.html" --include="*.vue" --include="*.svelte"。对于任何配置了allowedTracingUrls且未显式设置propagateTraceBaggage: false的项目,请在被追踪来源现有的Access-Control-Allow-Headers中添加"baggage",或设置propagateTraceBaggage: false以选择退出。 - 浏览器支持:最低要求为 Chrome 80+、Firefox 78+、Safari 14+(ES2020)。覆盖率约降低 0.048%。
常见错误
| 错误 | 后果 | 修复 |
|---|---|---|
将 forwardErrorsToLogs: true 替换为 forwardConsoleLogs: ['error'] | 未处理的错误(未捕获的异常、未处理的拒绝)将不再转发到 Logs | 保持 forwardErrorsToLogs: true 不变,并同时添加 forwardConsoleLogs: ['error']——两者的作用不同 |
更新了 startDurationVital 封装函数,却未更新调用方 | 调用方将旧的引用变量(现在为 undefined)传给 stopDurationVital——活跃项永远不会停止,也不会发出事件 | 更新封装函数后,搜索所有捕获返回值的调用方,并更新停止调用,直接传入活跃项名称字符串 |
stopDurationVital 调用中缺少 vitalKey 选项 | v7 的 stopDurationVital 需要 { vitalKey: string } 来标识要停止的活跃项 | 传入与 startDurationVital 中相同的字符串:stopDurationVital('name', { vitalKey: 'name' }) |
| 未检查 CDN/纯 JS 文件中的基于引用的活跃项 | TypeScript 项目会将此问题显示为类型错误;纯 JS 则会静默失效 | 明确运行步骤 2 中的 grep——不要依赖类型错误来查找所有位置 |
验证清单
升级后,请确认:
- SDK 加载时没有控制台错误
- 所有 CDN 脚本标签都包含
crossorigin="anonymous" - 初始化配置中没有对已移除选项的引用
- 会话回放录制正常工作(如果使用)
- 分布式追踪正常工作(没有来自 baggage 请求头的 CORS 错误)
- 首次页面加载后不再有
_dd_sCookie(应为_dd_s_v2) - 新隐私默认设置下的操作名称符合要求
- 没有变量捕获
startDurationVital(或其封装函数)的返回值——所有停止调用都直接使用活跃项名称字符串