首页 > 解决方案 > 与 NestJS 集成时,Sentry 未获取 TypeScript 源映射

问题描述

我最近创建了一个小型 NestJS 项目,我试图将 Sentry 集成到该项目中。我已按照Nest-Raven软件包自述文件中的说明以及 Sentry提供的 TypeScript 集成说明进行操作。

不幸的是,我似乎无法让 Sentry 显示 TypeScript 源映射,只有常规的 JS 源映射,如您在此处看到的:

哨兵源图

main.ts按照说明初始化了哨兵

import { NestFactory } from '@nestjs/core';
import { RewriteFrames } from '@sentry/integrations';
import * as Sentry from '@sentry/node';
import { AppModule } from './app.module';

// This allows TypeScript to detect our global value
declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace NodeJS {
    interface Global {
      __rootdir__: string;
    }
  }
}

global.__rootdir__ = __dirname || process.cwd();

async function bootstrap() {
  Sentry.init({
    dsn: 'https://mySentryDSN.ingest.sentry.io/0',
    integrations: [
      new RewriteFrames({
        root: global.__rootdir__,
      }),
    ],
  });
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

我还设置了Nest-Raven使用全局拦截器

import { APP_INTERCEPTOR } from '@nestjs/core';
import { RavenInterceptor, RavenModule } from 'nest-raven';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    RavenModule,
    ...
  ],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: APP_INTERCEPTOR,
      useValue: new RavenInterceptor(),
    },
  ],
})
export class AppModule {}

有没有其他人遇到过这个问题?我在想,也许我需要根据这些说明将源地图直接上传到 Sentry ,但据我所知,NestJS 不使用 Webpack,所以我不确定如何继续。

标签: typescriptnestjssource-mapssentry

解决方案


所以事实证明问题是我提供给RewriteFrames构造函数的目录。我最初global.__rootdir__Sentry Typescript 文档中复制了实现,但在调试过程中我发现__dirnameprocess.cwd()返回了不同的路径。

  dirname: '/Users/<name>/Documents/Projects/nest-test-project/dist',
  cwd: '/Users/<name>/Documents/Projects/nest-test-project'

由于__dirname返回的是一个真实值,因此为 Sentry 提供的路径是包含该dist文件夹的路径。一旦我更改了代码,为 Sentry 提供了项目的实际根路径,所有的 Typescript 源地图都被上传到了 Sentry。

编辑:有些人要求提供我tsconfig和上述代码的示例。我已经编写了自己SentryModule的引导哨兵,但改变的要点是找到你打电话的地方new RewriteFrames({...})并传递正确root的 ,在我的情况下是process.cwd().

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "ES2017",
    "lib": [ "ES2020.Promise" ],
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "sourceMap": true,
    "inlineSources": true,
    "sourceRoot": "/"
  }
}

main.ts或初始化哨兵的任何地方

import { RewriteFrames } from "@sentry/integrations";

Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  integrations: [
    new RewriteFrames({
      root: process.cwd(),
    }),
  ],
});

推荐阅读