# Source map

> Tải source map lên node để stack trace hiện đúng file, dòng và hàm gốc — kèm phần đã và chưa được kiểm chứng.

JavaScript trên production đã được thu nhỏ, nên stack trace gốc chỉ tới `index-4f2a1c.js:1:48213`. Khi source map được tải lên node, Belvador hiện đúng file, dòng, hàm và đoạn code xung quanh. Source map nằm trên node của bạn; không bao giờ được công khai cùng website.

## Cách hoạt động

1. Khi build, `sentry-cli sourcemaps inject` ghi một **Debug ID** vào mỗi file JavaScript và file `.map` của nó.
2. Bạn triển khai các file JavaScript đã được ghi Debug ID — **không kèm** file `.map`.
3. CI tải các file `.map` lên node bằng một token upload.
4. Khi có lỗi, SDK đã gắn Debug ID của các file trong stack. Node tìm source map khớp và khôi phục frame gốc.

Frame không khôi phục được sẽ có nhãn **Bản thu nhỏ** trong stack trace.

## Trước khi bắt đầu

- Một project và thư mục kết quả build, ví dụ `./dist`.
- Cùng một giá trị `release` trong `init` của SDK và khi tải lên, ví dụ mã commit.
- Một **token upload**: **Cài đặt project → Token upload → Token upload mới**. Token chỉ hiện một lần, có hạn 365 ngày, chỉ dùng cho project này — tải source map (tối đa 60 request mỗi giờ) và [ghi release và deploy](https://belvador.dev/vi/docs/releases) (600 mỗi giờ). Lưu thành biến bí mật trong CI tên `BELVADOR_UPLOAD_TOKEN`. Tạo và thu hồi token sẽ hỏi mã xác thực của bạn.

## Cách A — sentry-cli (khuyên dùng)

Edge của Belvador nhận API tải lên của sentry-cli. Chạy đoạn này trong CI sau bước build, trước khi triển khai:

```bash
export SENTRY_URL=https://edge.belvador.dev
export SENTRY_AUTH_TOKEN="$BELVADOR_UPLOAD_TOKEN"
export SENTRY_ORG=belvador SENTRY_PROJECT=<project-slug>
npx @sentry/cli sourcemaps inject ./dist
npx @sentry/cli sourcemaps upload --release "$RELEASE" ./dist
```

Cài đặt project → Token upload hiện đúng các lệnh này với địa chỉ project của bạn đã điền sẵn. `$RELEASE` phải là giá trị bạn truyền làm `release` trong `init`.

## Cách B — tải lên tarball

Không dùng lệnh upload của sentry-cli: ghi Debug ID, đóng gói source map rồi gửi lên:

```bash
npx @sentry/cli sourcemaps inject ./dist
(cd dist && find . -name '*.map' | tar -czf ../sourcemaps.tgz -T -)
curl -fsS -X POST "https://edge.belvador.dev/n/<node-id>/upload/sourcemaps?project=<project-id>&release=$RELEASE" \
  -H "Authorization: Bearer $BELVADOR_UPLOAD_TOKEN" \
  --data-binary @sourcemaps.tgz
```

Ứng dụng hiện lệnh này với node và project của bạn đã điền sẵn.

## Plugin của công cụ build

Plugin của Sentry cho công cụ build (Vite, webpack, esbuild, Rollup) dùng cùng API tải lên với sentry-cli, nên có thể tải lên Belvador khi trỏ tới `https://edge.belvador.dev` với token upload của bạn. Edge đã có sẵn hai cách sentry-cli và tarball trong bài này; với plugin, hãy kiểm tra kết quả bằng một lỗi thử.

## Giới hạn

| Giới hạn | Giá trị |
|---|---|
| Một file source map | 10 MiB |
| Số file mỗi lần tải | 1.000 |
| Tarball sau khi giải nén | 64 MiB |
| Request mỗi token | 60 mỗi giờ |
| Thời gian giữ source map | 90 ngày kể từ lần dùng cuối |

## Đừng triển khai file `.map`

Bỏ file `.map` khỏi bản triển khai, hoặc cấu hình hosting không phục vụ chúng. Ai tải được các file này đều đọc được mã nguồn gốc của bạn.

## Kiểm tra

1. Build, ghi Debug ID, tải lên và triển khai một release.
2. Tạo một lỗi thử trong release đó.
3. Mở issue: frame hiện tên file và dòng gốc, không còn nhãn **Bản thu nhỏ**.

Nếu frame vẫn ở dạng thu nhỏ:

- `release` trong `init` khác với giá trị đã tải lên;
- JavaScript đã triển khai không phải bản đã ghi Debug ID — `inject` phải chạy **trước** khi triển khai, trên đúng các file đó;
- việc tải lên thất bại: xem log CI có `401` (token sai hoặc đã thu hồi) hoặc `413` (file quá lớn);
- token đã hết hạn sau 365 ngày.

> [!NOTE]
> **Phần đã kiểm chứng:** việc SDK gắn Debug ID vào event và việc node khôi phục frame từ source map đã tải lên đều có test riêng của Belvador. Một lần chạy trọn vẹn từ CI tải lên tới một lỗi production chưa được ghi nhận, nên hãy kiểm tra release đầu tiên bằng một lỗi thử.
