Опция metafile: сбор информации о сборке

Включение метаданных сборки

metafile в esbuild включает генерацию структурированного описания результата бандлинга. Это JSON-объект, содержащий детализированную информацию о входных файлах, промежуточных модулях, выходных чанках и связях между ними.

Включение выполняется через API:

import * as esbuild from 'esbuild';

const result = await esbuild.build({
  entryPoints: ['src/index.js'],
  bundle: true,
  outfile: 'dist/bundle.js',
  metafile: true
});

В CLI:

esbuild src/index.js --bundle --outfile=dist/bundle.js --metafile=meta.json

Во втором случае метафайл записывается сразу в файл meta.json. В API-режиме он возвращается в объекте результата как result.metafile.


Структура метафайла

metafile представляет собой JSON с фиксированной схемой верхнего уровня:

  • inputs — все входные файлы и информация об их использовании
  • outputs — все сгенерированные файлы сборки

Пример общей структуры:

{
  "inputs": {
    "src/index.js": {
      "bytes": 120,
      "imports": ["react", "./app.js"]
    }
  },
  "outputs": {
    "dist/bundle.js": {
      "bytes": 24500,
      "inputs": ["src/index.js", "react/index.js"]
    }
  }
}

На практике структура значительно глубже и включает транзитивные зависимости, метаданные о переэкспортах и цепочках импортов.


Раздел inputs: анализ входных модулей

inputs описывает каждый модуль, который участвовал в сборке.

Каждый входной файл содержит:

  • bytes — размер исходного файла
  • imports — список импортируемых модулей
  • format — формат модуля (ESM/CommonJS)
  • dependsOn — косвенные зависимости через цепочку импортов

Пример:

{
  "src/app.js": {
    "bytes": 842,
    "imports": [
      {
        "path": "react",
        "kind": "import-statement"
      },
      {
        "path": "./utils.js",
        "kind": "require-call"
      }
    ]
  }
}

Ключевой момент: esbuild фиксирует не только факт импорта, но и его тип, что позволяет различать статические и динамические зависимости.


Раздел outputs: результат сборки

outputs содержит информацию о финальных артефактах сборки.

Каждый выходной файл включает:

  • inputs — все исходные модули, вошедшие в бандл
  • imports — внешние зависимости (external packages)
  • bytesInOutput — размер итогового файла
  • entryPoint — является ли файл точкой входа
  • cssBundle — если включена обработка CSS

Пример:

{
  "dist/bundle.js": {
    "entryPoint": "src/index.js",
    "inputs": [
      "src/index.js",
      "src/app.js",
      "node_modules/react/index.js"
    ],
    "bytes": 54321
  }
}

Эта информация позволяет точно определить, какие зависимости попали в конкретный бандл.


Анализ графа зависимостей

metafile фактически представляет собой сериализованный граф зависимостей.

Каждый узел — модуль, каждая связь — импорт. Это позволяет:

  • выявлять дублирование зависимостей
  • анализировать «тяжёлые» модули
  • понимать влияние конкретного импорта на итоговый размер

Пример анализа:

  • если один модуль импортируется в 40 местах, он станет центральным узлом графа
  • если зависимость не попала в outputs.inputs, она была исключена tree-shaking-ом

Использование для оптимизации сборки

Основные сценарии применения:

1. Поиск тяжёлых зависимостей

bytes в inputs и вклад в outputs позволяют определить модули, увеличивающие размер бандла.

2. Контроль tree-shaking

Если модуль присутствует в inputs, но его экспортов нет в outputs, значит он был полностью удалён.

3. Анализ дублирования

Одинаковые библиотеки могут попадать в разные чанки при неправильной конфигурации code splitting.

4. Проверка эффекта external-зависимостей

external модули отображаются в outputs.imports, но отсутствуют в inputs.


Интеграция с инструментами анализа

metafile является стандартным источником данных для внешних визуализаторов.

Типичные сценарии:

  • построение treemap зависимости
  • визуализация графа импортов
  • анализ бюджета бандла (bundle size budget)
  • CI-проверки на рост размера

Пример передачи в анализатор:

esbuild src/index.js --bundle --metafile=meta.json
npx esbuild-visualizer meta.json

Инкрементальный анализ сборок

metafile особенно полезен в связке с кешированием.

При сравнении двух файлов можно:

  • отслеживать изменение размеров модулей
  • выявлять новые зависимости
  • находить «раздувание» бандла

Пример логики сравнения:

old.metafile.inputs vs new.metafile.inputs
→ разница в bytes
→ новые зависимости
→ удалённые модули

Влияние опций сборки на metafile

Содержимое metafile зависит от конфигурации esbuild:

  • bundle: true — включает граф зависимостей
  • splitting: true — добавляет чанки в outputs
  • minify: true — меняет итоговые bytes
  • external — исключает зависимости из inputs
  • format — влияет на структуру импортов

Особенно сильно изменяется структура при включении code splitting: появляется несколько outputs, связанных общими inputs.


Ограничения и особенности

metafile не предназначен для runtime-использования. Это исключительно артефакт сборки.

Особенности:

  • не содержит исходного кода модулей
  • не хранит содержимое файлов, только метаданные
  • может значительно увеличивать размер JSON при больших проектах
  • требует отдельной обработки при визуализации

Практическая интерпретация данных

При анализе крупных проектов ключевым становится не сам JSON, а выводимые из него метрики:

  • размер по точкам входа
  • вклад зависимостей в каждый бандл
  • степень повторного использования модулей
  • плотность графа зависимостей

На основе этих данных строятся решения о:

  • разбиении чанков
  • удалении тяжёлых библиотек
  • замене зависимостей на более лёгкие аналоги