В экосистеме JavaScript работа с JSON традиционно считалась внешней
по отношению к модульной системе. В Node.js JSON долгое время
подключался через require(), а в браузере требовал либо
ручной загрузки через fetch, либо предварительной сборки. В
современных сборщиках, включая Esbuild, JSON рассматривается как
полноценный модуль первого класса, который может быть встроен
непосредственно в граф зависимостей.
В Esbuild поведение импорта JSON регулируется системой loader’ов. Loader определяет, каким образом конкретный тип файла преобразуется в JavaScript-модуль во время сборки. Для JSON существует специализированный loader, обеспечивающий преобразование структуры данных в экспортируемый объект.
При встрече импорта JSON-файла Esbuild выполняет статическую трансформацию содержимого файла в JavaScript-код. Исходный JSON:
{
"name": "app",
"version": "1.0.0",
"debug": true
}
Преобразуется в модульную форму:
var name = "app";
var version = "1.0.0";
var debug = true;
export {
name,
version,
debug
};
Фактическая реализация может отличаться в зависимости от режима сборки (ESM или CJS), но логика остаётся одинаковой: JSON становится статически анализируемым модулем.
В большинстве случаев Esbuild автоматически поддерживает JSON, однако при ручной настройке loader’ов необходимо явно указать тип обработки:
import * as esbuild from 'esbuild';
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
loader: {
'.json': 'json'
}
});
Здесь ключевым моментом является строка:
'.json': 'json'
Она определяет, что все файлы с расширением .json должны
обрабатываться встроенным JSON loader’ом.
После настройки loader JSON становится доступным для прямого импорта:
import config from './config.json';
console.log(config.name);
console.log(config.version);
В этом случае JSON интерпретируется как объект, экспортируемый по умолчанию.
Esbuild поддерживает оба формата модулей, и поведение JSON loader адаптируется под выбранную систему.
import data from './data.json';
export function getData() {
return data;
}
JSON становится default export.
const data = require('./data.json');
console.log(data);
Здесь Esbuild имитирует поведение Node.js, где JSON возвращается как обычный объект.
Одной из ключевых особенностей Esbuild является возможность инлайнинга JSON прямо в итоговый JavaScript-файл. Это означает отсутствие runtime-загрузки.
Исходный файл:
{
"apiUrl": "https://example.com",
"timeout": 5000
}
После сборки:
var config_default = {
apiUrl: "https://example.com",
timeout: 5000
};
Такой подход исключает необходимость дополнительных сетевых запросов или динамического парсинга JSON.
Esbuild способен выполнять частичную оптимизацию при использовании именованных экспортов из JSON. Если импортируется только часть данных:
import { apiUrl } from './config.json';
console.log(apiUrl);
На этапе сборки Esbuild может удалить неиспользуемые поля:
var apiUrl = "https://example.com";
export { apiUrl };
Это особенно эффективно при работе с большими конфигурационными файлами.
Использование JSON loader влияет на производительность сборки и выполнения кода по нескольким причинам:
Отсутствие runtime-парсинга JSON не читается
через JSON.parse во время выполнения.
Статический анализ Esbuild может заранее определить структуру данных.
Уменьшение количества HTTP-запросов В браузерных приложениях JSON встраивается в бандл.
Минимизация накладных расходов Node.js require В режиме bundling JSON не загружается динамически.
Несмотря на удобство, обработка JSON через Esbuild имеет ряд ограничений:
При использовании крупных JSON-структур целесообразно учитывать стратегию загрузки. Esbuild позволяет комбинировать JSON loader с code splitting:
esbuild.build({
entryPoints: ['src/app.js'],
bundle: true,
splitting: true,
format: 'esm',
loader: {
'.json': 'json'
}
});
В этом режиме JSON может быть вынесен в отдельные чанки при динамическом импорте:
const data = await import('./big-data.json');
Esbuild поддерживает динамическую загрузку JSON через
import():
async function loadConfig() {
const config = await import('./config.json');
return config.default;
}
Такой подход позволяет:
Рассмотрение JSON как модуля меняет архитектурный подход к разработке:
При использовании TypeScript импорт JSON через Esbuild требует либо
включённой опции resolveJsonModule, либо явной поддержки
loader:
{
"compilerOptions": {
"resolveJsonModule": true
}
}
После этого возможен импорт:
import settings from './settings.json';
settings.debug;
Esbuild в связке с TypeScript сохраняет типизацию, интерпретируя JSON
как any или строго типизированную структуру при наличии
деклараций.
Плагины могут перехватывать обработку JSON до встроенного loader’а. Это используется для:
Пример логики плагина:
const jsonPlugin = {
name: 'json-transform',
setup(build) {
build.onLoad({ filter: /\.json$/ }, async (args) => {
const fs = await import('fs');
const text = await fs.promises.readFile(args.path, 'utf8');
const data = JSON.parse(text);
return {
contents: `export default ${JSON.stringify(data)}`,
loader: 'js'
};
});
}
};
Такой механизм заменяет стандартный JSON loader собственным поведением.
Использование JSON loader в Esbuild приводит к смещению архитектурных границ:
Это делает JSON не внешним ресурсом, а частью компилируемой системы, управляемой сборщиком.