Source Maps: отладка prod кода

Source maps — файлы-маппинги, связывающие минифицированный/транспилированный код продакшна с исходным кодом, позволяя отлаживать в браузере с оригинальными именами переменных и номерами строк.

Зачем нужно

Продакшн-бандл — это минифицированный код вида a.b(c,d) в одну строку. При ошибке стек-трейс показывает бессмысленные строки и символы. Source maps позволяют браузеру (и Sentry) показывать оригинальный TypeScript-код с нормальными именами функций и точными строками.

Где используется

  • Отладка ошибок в DevTools при развёрнутом приложении
  • Sentry/Bugsnag — человекочитаемые stack traces в продакшне
  • TypeScript — маппинг .js.ts
  • Vite, webpack, esbuild — генерируют source maps как опция сборки

Как работают source maps

dist/app.js:1:847 → src/components/Button.tsx:42:10
Source map (.js.map) — JSON-файл содержит:
{
  "version": 3,
  "sources": ["src/app.ts"],
  "names": ["createUser", "validateEmail"],
  "mappings": "AAAA,SAASA..." // VLQ-кодированные позиции
}

Связь с файлом

// В конце минифицированного файла:
//# sourceMappingURL=app.js.map

// Или через заголовок HTTP-ответа:
SourceMap: /static/app.js.map

Настройка в сборщиках

Vite

// vite.config.ts
export default {
  build: {
    sourcemap: true,           // генерировать .js.map рядом с файлом
    // sourcemap: 'inline',    // встроить base64 в .js (увеличивает размер)
    // sourcemap: 'hidden',    // генерировать, но не добавлять ссылку в .js
  },
};

webpack

// webpack.config.js
module.exports = {
  mode: 'production',
  devtool: 'source-map',            // отдельный .js.map
  // devtool: 'hidden-source-map',  // .js.map без ссылки (для Sentry)
  // devtool: 'eval-source-map',    // быстро, только для разработки
};

TypeScript (tsconfig.json)

{
  "compilerOptions": {
    "sourceMap": true,          // генерировать .js.map
    "inlineSourceMap": false,   // не встраивать в .js
    "inlineSources": true,      // включить исходный .ts в .map
    "sourceRoot": "/src"        // базовый путь к источникам
  }
}

Использование в DevTools

1. Открыть DevTools (F12) → Sources
2. Если source maps подключены — в Sources видны оригинальные .ts/.tsx файлы
3. Брейкпоинты ставятся в исходном коде
4. Stack trace в Console показывает оригинальные строки

Source maps и Sentry

// При загрузке source maps в Sentry через CLI
npx @sentry/cli sourcemaps upload \
  --org my-org \
  --project my-project \
  --auth-token $SENTRY_TOKEN \
  dist/

// Или через Vite плагин
import { sentryVitePlugin } from '@sentry/vite-plugin';
export default {
  plugins: [sentryVitePlugin({ authToken: process.env.SENTRY_TOKEN })],
  build: { sourcemap: true },
};

Безопасность source maps

Открытые source maps → любой пользователь видит исходный код
Решения:
1. 'hidden' mode — .map файл генерируется, но не доступен публично
2. Загрузка в Sentry с удалением .map с сервера
3. Ограничение доступа к *.map через nginx
# nginx — запрет публичного доступа к source maps
location ~* \.js\.map$ {
  return 404;
}

Частые ошибки

  • Source maps в продакшне публично доступны — раскрывают исходный код
  • devtool: 'eval' в продакшне — не работает в браузерах с CSP
  • Не загружают source maps в Sentry — stack traces в ошибках нечитаемы
  • Нет inlineSources: true в TypeScript — Sentry не может показать код строки

Связанные темы

Ресурсы