Tree Shaking

了解如何通过 tree shaking 未使用的代码来减少 Sentry 打包大小。

Sentry SDK 以多种方式支持 tree shaking。为了充分利用现代打包工具(如 webpack 或 Rollup)的 tree shaking 功能,需要应用一些额外的配置。如果您希望最小化 Sentry SDK 的打包大小,我们建议阅读本页面并按照所示应用 tree shaking 配置。

Sentry SDK 包含了一些并非严格必需的代码,例如用于调试您的 Sentry 配置或启用跟踪的代码。虽然调试代码在开发环境中非常有用,但在生产环境中通常不需要包含这些代码,因为它们会占用宝贵的打包空间。JavaScript SDK 在其 CommonJS 和 ESM 发行版中包含了特殊的标志,可以在构建过程中帮助 tree shaking(移除)这类代码。

您没有导入和使用的任何代码将自动在使用现代打包工具(如 Webpack、Rollup、Vite 等)时被 tree shaken 掉。这意味着像 Replay、BrowserTracing、BrowserProfiling 等可选集成以及任何未使用的实用方法不会包含在您的打包中,除非您自己导入并使用了它们。本页面的其余部分涉及如何 tree shake 内部 SDK 代码,这些代码除非您使用某些特定功能,否则不是必需的。

此配置从打包工具插件 v2.9.0 版本开始可用。

如果您正在使用我们的某个打包工具插件,可以使用 bundleSizeOptimizations 配置选项来 tree shake 可选代码:

Copied
// For example, the @sentry/webpack-plugin passed to the webpack config
sentryPlugin({
  // other config
  bundleSizeOptimizations: {
    excludeDebugStatements: true,
    // Only relevant if you added `browserTracingIntegration`
    excludePerformanceMonitoring: true,
    // Only relevant if you added `replayIntegration`
    excludeReplayIframe: true,
    excludeReplayShadowDom: true,
    excludeReplayWorker: true,
  },
});

更多详情,请参阅您所使用的具体打包工具插件的文档:

如果您希望 tree shake 可选代码,可以通过替换 Sentry SDK 中的各种标志来从构建输出中移除这些代码。请注意,如果您已经通过 Sentry 打包工具插件配置了 tree shaking,则无需手动执行此操作——插件会为您处理。

以下标志可用:

__SENTRY_DEBUG__

将此标志替换为 false 将 tree shake 与调试日志相关的所有 SDK 代码。

__SENTRY_TRACING__

将此标志替换为 false 将 tree shake 与跟踪相关的所有 SDK 代码。

当您使用任何与跟踪相关的 SDK 功能(例如,Sentry.startTransaction())时,不要将 __SENTRY_TRACING__ 替换为 false。此标志旨在与像 @sentry/next@sentry/sveltekit 这样的包结合使用,这些包会自动包含跟踪功能。

如果未添加 browserTracingIntegration,这将不起作用。

__RRWEB_EXCLUDE_IFRAME__

将此标志替换为 true 将 tree shake 与 Session Replay 捕获 iframe 内容相关的所有 SDK 代码。仅在使用 Session Replay 时相关。如果您不想记录任何 iframe,请启用此标志。如果未添加 replayIntegration,这将不起作用。

__RRWEB_EXCLUDE_SHADOW_DOM__

将此标志替换为 true 将 tree shake 与 Session Replay 捕获 shadow DOM 元素相关的所有 SDK 代码。仅在使用 Session Replay 时相关。如果您不想记录任何 shadow DOM 元素,请启用此标志。如果未添加 replayIntegration,这将不起作用。

__SENTRY_EXCLUDE_REPLAY_WORKER__

将此标志替换为 true 将 tree shake 与 Session Replay 包含的压缩 Web Worker 相关的所有 SDK 代码。仅在使用 Session Replay 时相关。如果您希望自行托管压缩 Worker,请启用此标志。详情请参阅 使用自定义压缩 Worker除非您提供了自定义 Worker URL,否则不建议启用此标志。 如果未添加 replayIntegration,这将不起作用。

要在 webpack 打包中 tree shake Sentry 调试代码,我们建议使用 webpack 的 DefinePlugin

webpack.config.js
Copied
const webpack = require("webpack");

module.exports = {
  // ... other options
  plugins: [
    new webpack.DefinePlugin({
      __SENTRY_DEBUG__: false,
      __SENTRY_TRACING__: false,
      __RRWEB_EXCLUDE_IFRAME__: true,
      __RRWEB_EXCLUDE_SHADOW_DOM__: true,
      __SENTRY_EXCLUDE_REPLAY_WORKER__: true,
    }),
    // ... other plugins
  ],
};

如果您正在使用 rollup.js,我们建议使用 Rollup 的 replace 插件

rollup.config.js
Copied
import replace from "@rollup/plugin-replace";
import { terser } from "rollup-plugin-terser";

export default {
  // ... other options
  treeshake: "smallest", // recommended for best tree shaking results
  plugins: [
    replace({
      __SENTRY_DEBUG__: false,
      __SENTRY_TRACING__: false,
      __RRWEB_EXCLUDE_IFRAME__: true,
      __RRWEB_EXCLUDE_SHADOW_DOM__: true,
      __SENTRY_EXCLUDE_REPLAY_WORKER__: true,
    }),
    // ... other plugins (best placed after)
  ],
};

默认情况下,Sentry SDK 会设置一组 默认集成,以扩展您的 SDK 功能。您还可以在 SDK 配置中添加 其他自定义 集成。 如果您不希望在配置中包含默认集成,可以通过 禁用 它们并添加您自定义的集成数组来实现。 然而,如果您还想 tree shake 未使用的默认集成,可以通过自己创建一个 Client 来实现。通过这样做,您可以绕过通常为您创建 ClientSentry.init

以下示例展示了如何创建并绑定一个 Client,从而启用对未使用默认集成的 tree shaking:

main.js
Copied
import {
  BrowserClient,
  breadcrumbsIntegration,
  dedupeIntegration,
  defaultStackParser,
  getCurrentScope,
  globalHandlersIntegration,
  makeFetchTransport,
  linkedErrorsIntegration,
} from "@sentry/browser";

const client = new BrowserClient({
  // all options you normally pass to Sentry.init
  dsn: "your DSN",
  // ...
  transport: makeFetchTransport,
  stackParser: defaultStackParser,
  // Only the integrations listed here will be used
  integrations: [
    breadcrumbsIntegration(),
    globalHandlersIntegration(),
    linkedErrorsIntegration(),
    dedupeIntegration(),
  ],
});

getCurrentScope().setClient(client);
client.init();

Sentry.init 不同,Client 构造函数期望的选项类型是 ClientOptions 而不是 Options。这意味着 ClientOptions.integrations 属性是最终将被使用的所有集成的数组。